テキストファイルとバイナリファイルとは
ここではテキストファイルとかバイナリファイルと言ったときに、それがどんなデータをさすのか簡単に説明します。
ひとことでいうと、テキストファイルというのは、データを文字として扱っているということです。 一方、バイナリファイルというのはデータを文字としてみなしておらず、生のままデータを扱っているということになります。
#include <stdio.h>
#include <stdlib.h>
int main() {
int i = 12345;
FILE *fp = NULL;
if ((fp = fopen("foo.txt", "w")) == NULL) {
perror(NULL);
return 1;
}
fprintf(fp, "%d", i);
fclose(fp);
return 0;
}
この結果作成されたファイルをテキストエディタで開いてみます。
すると、次のように表示されました。
12345
int 型の変数 i に 12345 という数字を代入して、 それを書き出したので、ファイルをみても 12345 とみえる。大変素直でわかりやすいですね。
実際にファイルに何が書きこまれたか、バイト列として確認してみましょう。
cat foo.txt | xxd
00000000: 3132 3334 35 12345
cat コマンドはファイルの内容を標準出力に出力する Linux のコマンドで、 xxd コマンドは HEX データとして内容を出力します。上記のコマンドは cat コマンドの結果をパイプを通して、 xxd コマンドに渡したことになります。
プログラム内でははじめは整数の 12345 でしたが、 fprintf 関数を使って出力することにより、数字ではなく文字として出力されています。
バイナリデータとして出力する
それでは、int 型の変数 iをバイナリデータとして出力してみましょう。
#include <stdio.h>
#include <stdlib.h>
int main() {
int i = 12345;
FILE *fp = NULL;
if ((fp = fopen("foo.txt", "wb")) == NULL) {
perror(NULL);
return 1;
}
fwrite(&i, sizeof(int), 1, fp);
fclose(fp);
return 0;
}
上と同じようにテキストエディタで開いてみます。
すると、次のように表示されました。
90
なぜか "90" とみえています。
実は 10 進数の数字 12345 は 16 進数で 3039 です。 0x30 に対応する ASCII コードは 0、 0x39 は 9 です。
このため、12345 という数字をそのまま保存したら、たまたま文字として "90" が見えた、ということになります。
cat foo.txt | xxd
00000000: 3930 0000 90..
テキストファイルは基本的に、人が読んで直ちに理解可能なデータが格納されています。 わかりやすいとか、ポータブルなデータとしやすい代わり、一般的にデータサイズは大きくなります。
一方、バイナリーデータはデータサイズは小さくなるものの、人が読んでも通常意味が取れないので、 データレイアウトを厳密に定義しておく必要があります。