首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C 標準 I/O 實戰:fread/fwrite 二進位檔案完整複製指南

     編輯:關於C

場景需求

需將 .hex 格式韌體檔案完整複製,要求目標檔案與來源逐位元一致。使用標準庫 fread/fwrite 實現塊讀寫。

核心 API 速查

函式原型說明
freadsize_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)讀取 nmemb 個大小為 size 的項目,返回實際讀取項目數;0 表示 EOF 或錯誤。
fwritesize_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)寫入 nmemb 個大小為 size 的項目,返回實際寫入項目數。

關鍵參數選擇:size=1, nmemb=緩衝區大小

設 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;
}

常見坑點與避雷指南

  1. 文字模式 vs 二進位模式:Windows 下 "r"/"w" 會轉換換行符,導致二進位檔損壞,必須使用 "rb"/"wb"。
  2. 緩衝區型別:使用 unsigned char 或 uint8_t 避免符號擴展影響十六進位顯示。
  3. 檢查返回值:fread 返回 0 可能是 EOF 也可能是錯誤,建議搭配 ferror() 判斷。
  4. 大檔案支援:若檔案超過 2GB,需使用 fseeko/ftello 或 _fseeki64(Windows)。

進階驗證:逐位元組比對

# 複製後使用 cmp 或 md5sum 驗證
cmp src.hex dst.hex && echo "完全一致"
md5sum src.hex dst.hex

總結

fread/fwrite 配合 size=1 是二進位檔案流式複製的標準做法,簡單高效且可移植。掌握緩衝區大小調優、錯誤處理與跨平台模式差異,即可勝任嵌入式韌體更新、日誌歸檔等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved