11.5.3 fread_nolock_s(2)
这一段代码对streambufsize变量进行了赋值,如果文件自己有buffer,那么streambufsize就等于这个buffer的大小;如果文件没有使用buffer,那么fread_nolock_s就会使用一个内部的buffer,这个buffer的大小固定为_INTERNAL_BUFSIZ,即4096字节。接下来fread_nolock_s是一个循环:
while (count != 0) { |
if (anybuf(stream) && stream->_cnt != 0) |
在if的判断句中,anybuf判断文件是否有缓冲,而stream->_cnt != 0判断缓冲是否为空。因此当且仅当文件有缓冲且不为空时,这段代码才会执行。
让我们一行一行地来看这段代码的作用。nbytes代表这次要从缓冲中读取多少字节。在这里,nbytes等于还须要读取的字节数(count)与缓冲剩余的字节数(stream->_cnt)中较小的一个。
接下来的一行使用memcpy_s将文件stream里_ptr所指向的缓冲内容复制到data指向的位置,如图11-13所示。
|
| (点击查看大图)图11-13 文件缓冲区操作 |
接下来的5行,皆是按照图11-13修正FILE结构和局部变量的各种数据。
memcpy_s是memcpy的安全版本,相对于原始的memcpy版本,memcpy_s接受一个额外的参数记录输出缓冲区的大小,以防止越界,其余的功能和memcpy相同。
以上代码处理了文件缓冲不为空的情况,而如果缓冲为空,那么又分为两种情况:
(1)需要读取的数据大于缓冲的尺寸。
(2)需要读取的数据不大于缓冲的尺寸。
对于情况(1),fread将试图一次性读取尽可能多的整数个缓冲的数据直接进入输出的数组中,如果缓冲尺寸为0,则直接将剩下的数据一次性读取。代码如下:
else if (count >= bufsize) { |
else { |
stream->_cnt = _read(_fileno(stream), stream->_base, stream->_bufsiz); |
可以看见所有的线索都指向了_read函数。_read函数主要负责两件事:
(1)从文件中读取数据。
(2)对文本模式打开的文件,转换回车符。
| 回书目 上一节 下一节 |
