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