第36回
ファイルの扱い(1)~オープン/クローズと読み書き

オープンとクローズ

ファイル管理はOSの機能なので、同じOSならプログラミング言語を問わずほぼ同じ手順でファイルを扱えます(もちろん、命令語や文法は言語によって異なります)。

多くのOSは、ファイルを扱うためにまずオープン(open)という手続きを行い、読み書きを終えた後はクローズ(close)という手続きを採ります。Cでは、ファイルのオープンにfopen関数、クローズにfclose関数を用います。

ファイル構造体

プログラムがOSに対してファイルのオープンを依頼すると、OSは指定されたファイルをプログラムが操作できるように設定して、そファイルに関する情報をプログラムに渡します。プログラムは、その情報を通じてファイルの状態を把握できます。

Cでは、これがFILE型の構造体(FILE構造体)にまとめられます。fopen関数でファイルのオープンに成功すると、オープンしたファイルに関する情報を記録したFILE構造体が準備され、fopen関数からそれへのポインタが返されます。これを「ファイルポインタ」と呼び、オープンした後はファイルポインタを介してファイルに対する読み書きなどの操作を行います。

読み込もうとしたファイルが存在していないなどのエラーが発生した場合、fopen関数はNULLポインタを返します。その場合、プログラムはファイルに対する操作を行えないため、ユーザーにエラーメッセージを示すなどの措置を取ります。

fopen関数とfclose関数

fopen関数とfclose関数の書式を紹介しておきましょう。

・fopen関数
宣言:FILE *fopen(const char *filename, const char *mode);
機能:filenameで示したファイル(パス文字列を含む)をmodeで示すアクセスモードでオープンする。
戻り値 : オープンに成功した場合はfilenameへのファイルポインタ。失敗した場合はNULLポインタ。

アクセスモードはオープンしたファイルをどのように操作するかを示す記号で、以下のような種類があります。""で囲んだ『文字列』で指定することに注意しましょう。
r:読み込みモード
  ファイルが存在しない場合はエラーとなる。
w:新規作成モード
  新しくファイルを作成する。
  同名のファイルがすでにある場合、内容は上書きされる。
a:追加モード
  既存のファイルの最後尾に追加で書き出す。
  ファイルが存在しない場合はエラーとなる。

通常はテキストファイルとして読み書きを行います。バイナリ形式で読み書きする場合は、rwaそれぞれの文字にbを付け足して"wb"のように指定します。

読み書き両方が可能なモードでオープンする場合は+を付け足して"r+"のように指定します。"w+"も同じ意味です。

・fclose関数
宣言:int fclose(FILE *fp);
機能:fpで示したファイルをクローズする。
戻り値:クローズに成功した場合は0、失敗したときはEOF。

EOFは“End Of File”の略で、『ファイル終端』を示す記号です。stdio.hで定義されています。

開いたら必ず閉じる

オープンしたファイルはプログラムの終了時に自動的にクローズされ、FILE構造体のためのメモリも破棄(解放)されます。

しかし、たくさんのファイルを扱う大規模なプログラムでは、さまざまな場所でファイルをオープンしたりクローズしたりを繰り返します。そのような場合にファイルのクローズを省略すると、使われていないメモリ領域があちこちに残ったままとなります。

オープンしたファイルは用が済んだら即座に、かつ明示的にクローズするのがセオリーです。