C 言語でバイナリファイルを読み込む

胡金庫 2023年10月12日
  1. 関数 fread を使って C 言語でバイナリファイルを読み込む
  2. read 関数を用いて C 言語でバイナリファイルを読み込む
C 言語でバイナリファイルを読み込む

この記事では、C 言語でバイナリファイルを読み込む方法の複数の方法を示します。

関数 fread を使って C 言語でバイナリファイルを読み込む

fread は C 標準ライブラリの入出力機能の一部であり、通常のファイルからバイナリデータを読み込むために利用することができます。C 標準ライブラリは、バイナリファイルデータの読み書きを処理するためのプラットフォームに依存しないソリューションとともに、ユーザバッファリングされた I/O を実装しています。標準的な I/O 関数は、ファイルディスクリプタの代わりにファイルポインタで動作します。この関数はファイルのパスを文字列定数として受け取り、ファイルを開くモードを指定します。ファイルのモードは、ファイルを読み込むか、書き込むか、追加するかを指定します。しかし、各モード文字列には b という文字を含めてバイナリファイルのモードを明示的に指定することができます。

fopen がファイルポインタを返した後、バイナリストリームを読み込むために fread 関数を呼び出すことができます。fread は 4つの引数を取り、最初の引数は読み込んだバイトを格納する場所への void ポインタです。続く 2つの引数は、与えられたファイルから読み込む必要があるデータのサイズと数を指定します。最後に、この関数の第 4 引数はデータを読み込むべきファイルへの 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 はファイルディスクリプタ上で動作することに注意してください。この関数はさらに 2つの引数を取り、読み込んだデータが格納される 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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C File