バイナリファイル


今まで取り扱ってきたファイルはテキストファイルでした。バイナリファイルとは、コンピュータ内部で使用されるデータ形式をそのまま書込んであるファイルです。テキストエヂィタなどで開いても、意味のある文章にはなりません。テキストファイルでは、123という数値も"123"という文字列として書込まれています。

バイナリファイルの入出力は、基本的にはテキストファイルのそれと同じ方針でよいのですが、ファイルオープンモードや読込み•書込みのときに使用する関数がことなります。

  1. fopen 関数でファイルをオープンする。オープンモードは"rb","wb","ab"など b の文字が入ったものとなります。
  2. 書込むには fwrite 関数、読込みには fread 関数を使います。
  3. 読み書きが終了したら fclose 関数でファイルをクローズします。
size_t fwrite(
              const void *buffer,
              size_t size,
              size_t count,
              FILE *stream                                                                
);

bufferには、書込むデータへのポインタを指定します。size には、項目のサイズをバイト単位で指定します。普通は sizeof 演算子を利用するので size_t 型となっています。count には、書込む最大項目数を指定します。文字列などを書込む場合は strlen 関数を利用するので、size_t 型となっています。stream には、FILE 構造体へのポインタを指定します。戻り値は、実際に書込んだ項目数となります。

size_t fread(
             void *buffer,
             size_t size,
             size_t count,
             FILE *stream                                                                 
);

buffer には、データの格納場所を指定します。size には、項目のバイト数を指定します。count には、読み出す最大の項目を指定します。stream には、FILE 構造体へのポインタを指定します。戻り値は、実際に読み出した項目数となります。

バイナリファイルの書き込みには fwrite 関数を使う。

バイナリファイルの読込みには fread 関数を使う。

ソースコード

源文件
  1|/* binary01.c */                                                                      
  2|
  3|#include <stdio.h>
  4|
  5|int main(void)
  6|{
  7|  FILE *fp;
  8|  int a[3] = {1, 2, 3};
  9|  fp = fopen("mybinary.b", "wb");
 10|  if(fp == NULL){
 11|    perror("ファイルがオープンできません\n");
 12|    return -1;
 13|  }
 14|  fwrite(a, sizeof(int), 3, fp);
 15|  fclose(fp);
 16|  printf("ファイルに書込みました\n");
 17|
 18|  return 0;
 19|}

実行結果

ファイルに書込みました

これを実行すると mybinary.b というファイルが作られます。この中身をいすとエディタで開いてみて下さい。何だか分かりませんね。



では、文字列なども書込んでみましょう。

ソースコード

源文件
  1|/* binary02.c */                                                                      
  2|
  3|#include <stdio.h>
  4|#include <string.h>
  5|
  6|int main(void)
  7|{
  8|  FILE *fp;
  9|  char *str = "ABC";
 10|  int a[3] = {14, 15, 16};
 11|  fp = fopen("binary.b", "wb");
 12|  fwrite(str, sizeof(char), strlen(str), fp);
 13|  fwrite(a, sizeof(int), 3, fp);
 14|  fclose(fp);
 15|
 16|  printf("書き込み終了\n");
 17|
 18|  return 0;
 19|}

さて、この理屈がわかると、読み出し方法も分かりますね。この binary.b というバイナリファイルを読み出すプログラムを作ってみましょう。

ソースコード

源文件
  1|/* binary03.c */
  2|
  3|#include <stdio.h>
  4|#include <string.h>
  5|                                                                                      
  6|int main(void)
  7|{
  8|  FILE *fp;
  9|  int a[3];
 10|  char buf[8];
 11|
 12|  memset(buf, '\0', sizeof(buf[8]));
 13|
 14|  fp = fopen("binary.b", "rb");
 15|  fread(buf, sizeof(char), 3, fp);
 16|  fread(a, sizeof(int), 3, fp);
 17|  fclose(fp);
 18|  printf("%s, %d, %d, %d\n", buf, a[0], a[1], a[2]);
 19|
 20|  return 0;
 21|}
  

実行結果

ABC, 14, 15, 16

では、この際バイナリエディタもどきを作ってしまいましょう。これは、読込みの機能しかありません。ですから「エディタ」というのはおこがましいので「もどき」をうけています。

ソースコード

源文件

  1|/* bedit.c */                                                                         
  2|
  3|#include <stdio.h>
  4|
  5|int main(void)
  6|{
  7|  FILE *fp;
  8|  char fname[256];
  9|  unsigned char c;
 10|  int no = 0;
 11|
 12|  printf("ファイル名--");
 13|  scanf("%s", fname);
 14|
 15|  fp = fopen(fname, "rb");
 16|  if (fp == NULL) {
 17|    perror("ファイルオープンに失敗\n");
 18|    return -1;
 19|  }
 20|  while(fread(&c, sizeof(char), 1, fp) != 0) {
 21|    printf("%02X ", c);
 22|    no++;
 23|    if(no % 8 == 0)
 24|      printf("\n");
 25|  }                                                                                   
 26|  printf("\n");
 27|  fclose(fp);
 28|  return 0;
 29|}

実行結果

ファイル名--binary.b
41 42 43 0E 00 00 00 0F 
00 00 00 10 00 00 00 

ファイル入出力ができるようになると、かなり実用的なプログラムが作れます。プログラムにエラーが発生した場合にログファイルに記録することも可能でしょう。家計簿ソフトのようなもの作ることができますし、住所録だって作れます。

Chapte9 @ C言語目録 @ HomeWork List @ 昭亮's Homepage