在 C 語言中讀取二進位制檔案

Jinku Hu 2023年10月12日
  1. 使用 fread 函式讀取 C 語言中的二進位制檔案
  2. 使用 read 函式讀取 C 語言中的二進位制檔案
在 C 語言中讀取二進位制檔案

本文將演示如何在 C 語言中讀取二進位制檔案的多種方法。

使用 fread 函式讀取 C 語言中的二進位制檔案

fread 是 C 標準庫輸入/輸出設施的一部分,可以利用它從普通檔案中讀取二進位制資料。C 標準庫實現了一個使用者緩衝 I/O 以及一個獨立於平臺的解決方案來處理二進位制檔案資料的讀/寫。標準 I/O 函式在檔案指標上操作,而不是檔案描述符。FILE*流由 fopen 函式檢索,該函式將檔案路徑作為字串常量和開啟它們的模式。檔案的模式指定了開啟檔案是讀、寫還是追加。不過要注意,每個模式字串可以包含字母 b 來明確指定二進位制檔案模式,這可能會被一些非 UNIX 系統解釋為對文字和二進位制檔案的不同處理。

fopen 返回檔案指標後,我們可以呼叫 fread 函式來讀取二進位制流。fread 需要四個引數,其中第一個引數是 void 指標,指向讀取的位元組應該儲存的位置。接下來的兩個引數指定需要從給定檔案中讀取的資料項的大小和數量。最後,函式的第四個引數是應該從其中讀取資料的 FILE 指標。在下面的例子中,我們開啟並向名為 input.txt 的檔案寫入一些任意位元組。然後,我們關閉該檔案並再次開啟它進行讀取。

#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

const uint8_t data[] = {0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72,
                        0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
                        0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x77,
                        0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x74,
                        0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65};

const char* filename = "input.txt";

int main(void) {
  FILE* output_file = fopen(filename, "wb+");
  if (!output_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  fwrite(data, 1, sizeof data, output_file);
  printf("Done Writing!\n");
  fclose(output_file);

  FILE* in_file = fopen(filename, "rb");
  if (!in_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* file_contents = malloc(sb.st_size);
  fread(file_contents, sb.st_size, 1, in_file);

  printf("read data: %s\n", file_contents);
  fclose(in_file);

  free(file_contents);
  exit(EXIT_SUCCESS);
}

輸出:

Done Writing!
read data: Temporary string to be written to file

使用 read 函式讀取 C 語言中的二進位制檔案

或者,我們可以使用 read 函式,它本質上是一個系統呼叫。請注意,read 對檔案描述符起作用;因此檔案應該用 open 系統呼叫開啟。它需要額外的兩個引數,表示讀取的資料將被儲存的 void 指標和要從檔案中讀取的位元組數。請注意,我們正在讀取檔案的全部內容,並使用 malloc 函式為其動態分配記憶體。利用 stat 系統呼叫來查詢檔案大小。

#include <fcntl.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

const uint8_t data[] = {0x54, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72,
                        0x79, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
                        0x20, 0x74, 0x6f, 0x20, 0x62, 0x65, 0x20, 0x77,
                        0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x74,
                        0x6f, 0x20, 0x66, 0x69, 0x6c, 0x65};

const char* filename = "input.txt";

int main(void) {
  FILE* output_file = fopen(filename, "wb+");
  if (!output_file) {
    perror("fopen");
    exit(EXIT_FAILURE);
  }

  fwrite(data, 1, sizeof data, output_file);
  printf("Done Writing!\n");
  fclose(output_file);

  int fd = open(filename, O_RDONLY);
  if (fd == -1) {
    perror("open\n");
    exit(EXIT_FAILURE);
  }

  struct stat sb;
  if (stat(filename, &sb) == -1) {
    perror("stat");
    exit(EXIT_FAILURE);
  }

  char* file_contents = malloc(sb.st_size);
  read(fd, file_contents, sb.st_size);

  printf("read data: %s\n", file_contents);
  close(fd);

  free(file_contents);

  exit(EXIT_SUCCESS);
}

輸出:

Done Writing!
read data: Temporary string to be written to file
作者: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

DelftStack.com 創辦人。Jinku 在機器人和汽車行業工作了8多年。他在自動測試、遠端測試及從耐久性測試中創建報告時磨練了自己的程式設計技能。他擁有電氣/ 電子工程背景,但他也擴展了自己的興趣到嵌入式電子、嵌入式程式設計以及前端和後端程式設計。

LinkedIn Facebook

相關文章 - C File