1、
size_t fread(void *buffer,size_t elementsize,size_t count,FILE*stream)
returnfread_s(buffer,SIZE_MAX,elementsize,count,stream). //可以看出所有工作都交给了fread_s.
2、
size_t _cdecl fread_s(void *buffer,size_t buffersize,size_telementsize,size_t count,FILE *stream) //多了一个buffer的大小,这个参数直接被定义为SIZE_MAX,表明fread不关心这个参数,而用户使用这个函数的时候可以指定这个参数防止越界的目的。
_lock_str(stream);
retval=_fread_nolock_s(buffer,buffersize,elementsize,count,stream);
_unlock_str(stream);
return reval;
可以看到fread_s 将工作交给了_fread_nolock_s.本函数实现了互斥访问。
3、
size_t _cdecl _fread_nolock_s(void *buffer,size_tbuffersize,size_t elementsize,size_t num,FILE *stream)
char *data;//指向buffer的开头
size_t datasize;//剩余buffer大小
size_t count;//记录没有读取的字节数
size_t total;//记录了共需要的字节数
unsigned streambufsize;//记录了文件缓冲的大小
unsigned nbytes;
unsigned nread;
int c;
//初始化
data=buffer;datasize=buffersize;
count = total =elementsize*num;
if(anybuf(stream))//检查文件是否使用了缓冲技术
streambufsize=stream->_bufsize;
else
streambufsize=_INTERNAL_BUFSIZE;//文件内部buffer,4096字节
while(count!=0)
read data
decrease count
4、FILE的结构
struct _iobuf
char *ptr;//缓冲区开头
int _cnt;//剩余没有读的字节个数
char *_base;//指向一个字符数组,就是这个文件的缓冲
int _flag;//打开文件的属性
a、_IOYOURBUF 用户自己设置setbuf
b、_IOMYBUF 文件内部缓冲
c、_IONBF 单字节缓冲,就是charbuf
int _file;
int _charbuf;//单字节缓冲
int _bufsize;//缓冲的大小
char *_tmpfname;
typedef struct _iobuf FILE;
5、读取文件时buffer的操作
a、文件缓冲中还有数据,优先都去缓冲区
if(anybuf(stream) &&stream->_cnt!=0)
nbytes=(count < stream -> _cnt) ?count : stream->_cnt;
memcpy_s(data,datasize,stream->ptr,nbytes);
b、文件缓冲空(需要重新系统调用)
1)需要读取的数据大于缓冲,fread试图一次都去最多的数据,直接送到数组中。
else if(count >=bufsize)
nbytes=(bufsize ?(unsigned)(count-count%bufsize):(ungned)count);//如果有缓冲计算缓冲剩余空间,如果没有缓冲直接都取全部
nread=_read(_fileno(stream),data,nbytes);//调用_read函数
2)读取的数据不大于缓冲区
else{
if(c=_filbuf(stream))==EOF)
//filbuf是一个宏_read(fileno(stream,stream->_base,stream->bufsiz));
return (total-count)/size;
6、_read函数
a、从文件中都去数据
b、对文本模式打开的文件,转换回车符号