设为首页 加入收藏

TOP

1.5 fread实现
2013-10-07 00:44:23 来源: 作者: 【 】 浏览:58
Tags:1.5 fread 实现

1.5  fread实现

我们知道C语言的运行库十分庞大,前面介绍的启动部分、多线程、全局构造和析构这些内容其实都不是占CRT篇幅最大的部分。与任何系统级别的软件一样,真正复杂的并且有挑战性的往往是软件与外部通信的部分,即IO部分。

前面的章节中对运行库的分析都是比较粗略的,虽然涉及运行库的各个方面,但是在运行库实现的深度上挖掘得不够。我们知道,IO部分实际上是运行库中最为重要也最为复杂的部分之一,在结束本章之前,最后来仔细了解C语言标准库中一个非常重要的IO函数fread的具体实现,我们知道fread最终是通过Windows的系统API: ReadFile()来实现对文件的读取的,但是从fread到ReadFile之间究竟发生了什么却是一个未知的迷。我们希望通过对fread()的挖掘,能够打通从运行库函数fread到Windows系统API的ReadFile()函数之间的这条通路,这有助于对运行库和IO的进一步了解。

首先我们来看fread的函数声明:

size_t fread(
void *buffer,
size_t elementSize,
size_t count,
FILE *stream
)

在这里,size_t是表示数据大小的类型,定义为unsigned int。fread有4个参数,其功能是尝试从文件流stream里读取count个大小为elementSize个字节的数据,存储在buffer里,返回实际读取的字节数。

ReadFile的函数声明为:

BOOL ReadFile( 
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);

ReadFile的第一个参数hFile为所要读取的文件句柄,我们在本章的第一节就已经介绍了句柄的概念及讨论了为什么要使用句柄的原因,与它对应的应该是fread里面的stream参数;第二个参数lpBuffer是读取文件内容的缓冲区,相对应的fread参数为buffer;第三个参数nNumberOfBytesToRead为要读取多少字节,fread与它相对应的应该是两个参数的乘积,即elementSize * count;第四个参数lpNumberOfBytesRead为一个指向DWORD类型的指针,它用于返回读取了多少个字节;最后一个参数是没用的,可以忽略它。

在了解了fread函数和ReadFile函数之后,可以发现它们在功能上看似完全相同,而且在参数上几乎一一对应,所以如果我们要实现一个最简单的fread,就是直接调用ReadFile而不做任何处理:

size_t fread(
void *buffer,
size_t elementSize,
size_t count,
FILE *stream
) {
DWORD bytesRead = 0;
BOOL ret = ReadFile(
stream->_file // FILE结构的文件句柄
, buffer
, elementSize * count
, &bytesRead
, NULL
);
    if(ret)
return bytesRead;
else
return -1;
}
可能很多人会觉得很奇怪,既然fread可以这么简单地实现,为什么CRT还要做得这么复杂呢?先别着急,我们接下来就慢慢来看CRT是怎么实现fread的,为什么它要这么做。
【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇11.4.2 MSVC CRT的全局构造和析构.. 下一篇11.5.1 缓冲

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: