23. fread和fwrite的读写缓冲区

fwrite(buff, sizeof(buff), 1, pFile);//返回实际写入的完整项数,参数3尽量填1,简单粗暴
fread(buff, sizeof(buff), 1, pFile);//返回实际读取的完整项数,参数3尽量填1,简单粗暴

  

文件内容:

 23. fread和fwrite的读写缓冲区

 

 

4字节复制旧文件到新文件,忽略错误检查:

FILE *pFileSource = fopen("C++ Primer.exe", "rb");//CreateFile
FILE *pFileDest = fopen("C++ Primer2.exe", "wb");

char buffSource[16] = { 0 };//设置很小的缓冲区,便于测试
char buffDest[16] = { 0 };
setvbuf(pFileSource, buffSource, _IOFBF, 7);//只给7字节,便于测试
setvbuf(pFileDest, buffDest, _IOFBF, 7);

fseek(pFileSource, 0, SEEK_END);
long fileSize = ftell(pFileSource);

rewind(pFileSource);
unsigned int buff = 0;
for (long i = 0; i < fileSize / 4; i++) {
    fread(&buff, sizeof(buff), 1, pFileSource);//ReadFile
    fwrite(&buff, sizeof(buff), 1, pFileDest);//直接写入缓冲区,满了调用flush
}
unsigned char byte = '';
for (long i = 0; i < fileSize % 4; i++) {
    fread(&byte, sizeof(byte), 1, pFileSource);
    fwrite(&byte, sizeof(byte), 1, pFileDest);
}

fflush(pFileDest);//WriteFile
fclose(pFileSource);//CloseHandle
fclose(pFileDest);

以上代码将缓冲区大小设为7,但是实际向下舍入到 2的整数倍,即6字节。

23. fread和fwrite的读写缓冲区

 

23. fread和fwrite的读写缓冲区

 

 

 

1次fread读取6字节填满缓冲区,再取出4字节给代码中的unsigned int buff = 0;此变量在0019FF0C处。

23. fread和fwrite的读写缓冲区

 

 

 

 

F10单步,第1fwrite写入4字节到写缓冲区,watch切换到pFileDest观察。再观察要写入的文件,发现大小没写入任何数据,因为写缓冲区没满。

23. fread和fwrite的读写缓冲区

 

 

 

 

 

 

 

F10单步,第2fread读取6字节

23. fread和fwrite的读写缓冲区

 

 

 

 

F10单步,第2fwrite0506写入缓冲区末尾,这时满了,将整个6字节缓冲区写入文件。再调整_ptr_base,并把0708写入缓冲区。打开文件,发现有6字节数据。

23. fread和fwrite的读写缓冲区

 

 

23. fread和fwrite的读写缓冲区

 

 

 

 

F10单步,第3fread,缓冲区数据足够,未读入新数据,有变化的是_ptr

23. fread和fwrite的读写缓冲区

 

 

 

 

 

 

 

F10单步,第3fwrite,刚好填满写缓冲区,打开文件发现依旧是6字节,未写入。

23. fread和fwrite的读写缓冲区

 

 

 

 

F10单步,第4fread,读入6字节新数据

 

 

 

 23. fread和fwrite的读写缓冲区

 

 

 

F10单步,第4fwrite,缓冲区已满,调用fflush,打开文件发现多了6字节

23. fread和fwrite的读写缓冲区

 

 23. fread和fwrite的读写缓冲区

 

 

总结:第一次freadfwrite时会分别提供默认4096字节的读和写缓冲区,也可以自己调用setvbuf函数设置缓冲区。fread从文件读取_bufsiz大小的数据存放在读缓冲区,后续如无必要,不会读文件,而是直接读缓冲区。同理,fwrite将数据写入写缓冲区,除非缓冲区已满,否则不写入文件。两者都通过移动指针_ptr读取缓冲区和写入缓冲区。

 

原文链接: https://www.cnblogs.com/Nutshelln/p/12817343.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    23. fread和fwrite的读写缓冲区

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/345863

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午3:30
下一篇 2023年3月2日 上午3:30

相关推荐