设为首页 加入收藏

TOP

11.5.3 fread_nolock_s(1)
2013-10-07 00:46:11 来源: 作者: 【 】 浏览:88
Tags:11.5.3 fread_nolock_s

11.5.3  fread_nolock_s(1)

fread_nolock_s是进行实际工作的函数,为了便于理解,下面会分段列出fread_nolock_s的实现,并且将省去所有的参数检查和错误检查。同样,还将省去64位部分的代码。

fread -> fread_s -> _fread_nolock_s:
size_t __cdecl _fread_nolock_s(
void *buffer,
size_t bufferSize,
size_t elementSize,
size_t num,
FILE *stream
)
{
char *data;
size_t dataSize;
size_t total;
size_t count;
unsigned streambufsize;
unsigned nbytes;
unsigned nread;
int c;
    data = buffer;
dataSize = bufferSize;
    count = total = elementSize * num;
这一段是fread_nolock_s的初始化部分。在它的局部变量中,data将始终指向buffer中尚未被写入的起始部分。在最开始的时候,data指向buffer的开头。dataSize记录了buffer中还可以写入的字节数,理论上,data + dataSize = buffer + bufferSize。如图11-12所示。
 
(点击查看大图)图11-12  data、buffer、bufferSize和dataSize

total变量记录了总共须要读取的字节数,count则记录在读取过程中尚未读的字节数。streambufsize记录了文件缓冲的大小。剩下的3个局部变量在代码的分析过程中会一一提到。在这里需要特别提一下缓冲在FILE结构中的具体实现。

在对缓冲的概念有了一定了解之后,可分析一下文件类型FILE结构的定义了。FILE的定义位于stdio.h里:

struct _iobuf {
char *_ptr;
int   _cnt;
char *_base;
int   _flag;
int   _file;
int   _charbuf;
int   _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
在这里,_base字段指向一个字符数组,即这个文件的缓冲,而_bufsiz记录着这个缓冲的大小。_ptr和fread_nolock_s的局部变量data一样,指向buffer中第一个未读的字节,而_cnt记录剩余未读字节的个数。_flag记录了FILE结构所代表的打开文件的一些属性,目前我们感兴趣的是3个标志:
#define _IOYOURBUF   0x0100
#define _IOMYBUF     0x0008
#define _IONBF       0x0004
在这里,_IOYOURBUF代表这个文件使用用户通过setbuf提供的buffer,_IOMYBUF代表这个文件使用内部的缓冲,而_IONBF代表这个文件使用一个单字节的缓冲,即缓冲大小仅为1个字节。这个缓冲就是_charbuf变量。此时,_base变量的值是无效的。接下来继续看fread_nolock_s的代码:
    if (anybuf(stream))
{
streambufsize = stream->_bufsiz;
}
else
{
streambufsize = _INTERNAL_BUFSIZ;
}
anybuf函数的定义位于file2.h:
#define anybuf(s) \
((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF))
事实上anybuf并不是函数,而是一个宏,它仅检查这个FILE结构的_flag变量里有没有前面提到的3个标志位的任意一个,如果这3个标志位在_flag中存在任意一个,就说明这个文件使用了缓冲。
【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇11.5.3 fread_nolock_s(2) 下一篇11.5.2 fread_s

评论

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