fread/fwrite 原型
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
size:單一元素大小(位元組);
nmemb:元素個數;
- 回傳**成功讀寫的元素數**(非位元組數);
- 讀取到 EOF 回傳 0,錯誤回傳 0 並設
ferror。
完整複製程式(十六進位列印驗證)
#include <stdio.h>
#define BUFSIZE 512
int main() {
FILE *fr = fopen("D:\\LED.hex", "rb");
FILE *fw = fopen("D:\\test.hex", "wb");
if (!fr || !fw) { perror("open"); return 1; }
unsigned char buf[BUFSIZE];
size_t n, cnt = 0;
while ((n = fread(buf, 1, BUFSIZE, fr)) > 0) {
for (size_t i = 0; i < n; i++) printf("%02X ", buf[i]);
fwrite(buf, 1, n, fw);
cnt++;
}
printf("\nRead blocks: %zu\n", cnt);
fclose(fr); fclose(fw);
return 0;
}
關鍵實驗發現
- size=1, nmemb=BUFSIZE:每次最多讀 BUFSIZE 位元組,回傳實際位元組數,**最通用、最安全**;
- size=BUFSIZE, nmemb=1:若檔案長度非 BUFSIZE 倍數,最後一次讀取會失敗(回傳 0),導致資料遺失;
- 緩衝區型別
char/unsigned char/short 不影響複製正確性,**只要 size=1 即可逐位元組搬移**;
- 列印格式
%02X 需配合 unsigned char 避免負數擴展。
最佳實踐建議
- 固定使用
fread(buf, 1, BUFSIZE, fp) 逐位元組讀取;
- 寫入時同樣
fwrite(buf, 1, n, fp),n 為實際讀取數;
- 大檔案建議 BUFSIZE 4KB~64KB 對齊磁碟區塊;
- 檢查
ferror 區分 EOF 與真正錯誤。