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

C語言二進制文件讀寫完全指南:fopen/fread/fwrite/fseek 深度解析

     編輯:關於C語言

前言:二進制 IO——系統編程的基石

二進制文件讀寫不進行任何格式轉換,**字節流 1:1 傳輸**,是文件拷貝、序列化、多媒體處理、嵌入式固件升級的核心操作。本文系統講解 fopen 模式、fread/fwrite 參數語義、fseek 定位機制,並給出標準文件拷貝程序與各函數權威參考手冊。

一、 核心拷貝程序:標準范式

#include <stdio.h>
#include <stdlib.h>

#define MAXLEN 1024

int main(int argc, char *argv[]) {
    if (argc < 3) {
        fprintf(stderr, "Usage: %s infile outfile\n", argv[0]);
        return 1;
    }

    FILE *infile = fopen(argv[1], "rb");   // 二進制讀
    FILE *outfile = fopen(argv[2], "wb");  // 二進制寫 (截斷/創建)
    if (!infile || !outfile) {
        perror("fopen");
        return 1;
    }

    unsigned char buf[MAXLEN];
    size_t rc;
    while ((rc = fread(buf, 1, MAXLEN, infile)) > 0) {
        fwrite(buf, 1, rc, outfile);  // 關鍵:寫入實際讀到的字節數 rc
    }

    fclose(infile);
    fclose(outfile);
    return 0;
}

關鍵細節

  • fread` 返回**實際讀取項數** (此處項大小=1),EOF 或錯誤返回 0/短計數。
  • fwrite` 必須用 `rc` 作為項數,而非 `MAXLEN`,否則最後一塊會寫入垃圾數據。
  • rb`/`wb` 模式:Windows 下關鍵 (禁用 \r\n 轉換),Linux/Unix 忽略 `b` 但建議保留以提高可移植性。

二、 三大核心函數權威詳解

1. fopen:打開文件流

FILE *fopen(const char *path, const char *mode);
模式含義文件不存在文件存在指針初始位置
r只讀文本失敗保留文件頭
r+讀寫文本失敗保留文件頭
w只寫文本創建**截斷為 0**文件頭
w+讀寫文本創建**截斷為 0**文件頭
a追加文本創建保留文件尾
a+讀追加文本創建保留文件尾
rb/wb/ab/rb+/wb+/ab+對應二進制版本同上同上同上
  • 返回 FILE* 成功,NULL 失敗 (檢查 errno)。
  • 新文件權限受 umask 影響,默認 0666。

2. fread:從流讀取

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 讀取 nmemb 個項,每項 size 字節,總計 size*nmemb 字節。
  • 返回**實際讀取項數** (可能 < nmemb),需配合 feof()/ferror() 區分 EOF 與錯誤。
  • 常用模式:fread(buf, 1, MAXLEN, fp) (項大小 1,項數 = 字節數)。

3. fwrite:寫入流

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
  • 寫入 nmemb 項,返回實際寫入項數 (磁盤滿/錯誤時短計數)。
  • 緩衝策略受 setvbuf 控制 (全緩衝/行緩衝/無緩衝)。

三、 fseek`:隨機訪問定位

int fseek(FILE *stream, long offset, int whence);
whence常量值含義
SEEK_SET0從文件頭偏移 offset 字節
SEEK_CUR1從**當前位置**偏移 offset 字節
SEEK_END2從文件尾偏移 offset 字節 (通常負值)
  • 成功返回 0,失敗 -1。
  • 文本流僅支持 SEEK_SET 配合 0 或 ftell 返回值,其他行為未定義。
  • 二進制流任意偏移安全。
  • 調用後**清除 EOF 標志**,不影響錯誤標志。

四、 進階話題:ftell/fgetpos/fsetpos/rewind

  • ftell:返回長整型偏移 (二進制流為字節數,文本流為魔術值)。
  • fgetpos/fsetpos:使用 fpos_t 不透明類型,支持大文件 (>2GB) 和文本流安全定位。
  • rewind(fp):等價 fseek(fp, 0, SEEK_SET) + clearerr(fp)。

五、 總結

二進制 IO 三板斧:正確模式打開 → fread/fwrite 循環配合實際計數 → fseek 隨機定位。記住 rb/wb 可移植性、rc` 回傳值語義、文本/二進制流定位差異,即可駕馭 99% 文件讀寫場景。

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