23. fread和fwrite的讀寫緩沖區


fwrite(buff, sizeof(buff), 1, pFile);//返回實際寫入的完整項數,參數3盡量填1,簡單粗暴
fread(buff, sizeof(buff), 1, pFile);//返回實際讀取的完整項數,參數3盡量填1,簡單粗暴

  

文件內容:

 

 

 

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 = '\0';
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字節。

 

 

 

 

1次fread讀取6字節填滿緩沖區,再取出4字節給代碼中的unsigned int buff = 0;此變量在0019FF0C處。

 

 

 

 

F10單步,第1fwrite寫入4字節到寫緩沖區,watch切換到pFileDest觀察。再觀察要寫入的文件,發現大小沒寫入任何數據,因為寫緩沖區沒滿。

 

 

 

 

 

 

 

F10單步,第2fread讀取6字節

 

 

 

 

F10單步,第2fwrite0506寫入緩沖區末尾,這時滿了,將整個6字節緩沖區寫入文件。再調整_ptr_base,並把0708寫入緩沖區。打開文件,發現有6字節數據。

 

 

 

 

 

 

F10單步,第3fread,緩沖區數據足夠,未讀入新數據,有變化的是_ptr

 

 

 

 

 

 

 

F10單步,第3fwrite,剛好填滿寫緩沖區,打開文件發現依舊是6字節,未寫入。

 

 

 

 

F10單步,第4fread,讀入6字節新數據

 

 

 

 

 

 

 

F10單步,第4fwrite,緩沖區已滿,調用fflush,打開文件發現多了6字節

 

 

 

 

總結:第一次freadfwrite時會分別提供默認4096字節的讀和寫緩沖區,也可以自己調用setvbuf函數設置緩沖區。fread從文件讀取_bufsiz大小的數據存放在讀緩沖區,后續如無必要,不會讀文件,而是直接讀緩沖區。同理,fwrite將數據寫入寫緩沖區,除非緩沖區已滿,否則不寫入文件。兩者都通過移動指針_ptr讀取緩沖區和寫入緩沖區。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM