需將 .hex 格式韌體檔案完整複製,要求目標檔案與來源逐位元一致。使用標準庫 fread/fwrite 實現塊讀寫。
| 函式 | 原型 | 說明 |
|---|---|---|
| fread | size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) | 讀取 nmemb 個大小為 size 的項目,返回實際讀取項目數;0 表示 EOF 或錯誤。 |
| fwrite | size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) | 寫入 nmemb 個大小為 size 的項目,返回實際寫入項目數。 |
設 size = 1、nmemb = BUFSIZE,則返回值直接等於位元組數,便於處理非固定長度的最後一塊。
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 512
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s \n", argv[0]);
return 1;
}
FILE *fpr = fopen(argv[1], "rb"); // 二進位讀取
FILE *fpw = fopen(argv[2], "wb"); // 二進位寫入
if (!fpr || !fpw) {
perror("File open failed");
return 1;
}
unsigned char buf[BUFSIZE];
size_t nRead, totalBlocks = 0;
while ((nRead = fread(buf, 1, BUFSIZE, fpr)) > 0) {
// 可選:十六進位輸出前 16 位元組驗證
if (totalBlocks == 0) {
for (size_t i = 0; i < nRead && i < 16; ++i)
printf("%02X ", buf[i]);
putchar('\n');
}
fwrite(buf, 1, nRead, fpw); // 原樣寫入
++totalBlocks;
}
printf("複製完成,共讀寫 %zu 個塊。\n", totalBlocks);
fclose(fpr);
fclose(fpw);
return 0;
}
"r"/"w" 會轉換換行符,導致二進位檔損壞,必須使用 "rb"/"wb"。unsigned char 或 uint8_t 避免符號擴展影響十六進位顯示。fread 返回 0 可能是 EOF 也可能是錯誤,建議搭配 ferror() 判斷。fseeko/ftello 或 _fseeki64(Windows)。# 複製後使用 cmp 或 md5sum 驗證 cmp src.hex dst.hex && echo "完全一致" md5sum src.hex dst.hex
fread/fwrite 配合 size=1 是二進位檔案流式複製的標準做法,簡單高效且可移植。掌握緩衝區大小調優、錯誤處理與跨平台模式差異,即可勝任嵌入式韌體更新、日誌歸檔等場景。