14. ライブラリ関数(9/36) - 入出力ライブラリ(8/10)
14.12 バッファ操作関数
通常、ファイルはハードディスク(HDD)に作成しますが、ハードディスクの動作はCPUやメモリと比べると大変に低速です。これをカバーするために、出力データをメモリ上のバッファ領域に溜め込んでおき、バッファが満杯になったあるいは、一定時間経過した時点でハードディスクに出力する、といったことを行っています。通常は、これで問題ないと思いますが、入出力データや媒体の種類により、バッファを経由したくないことがあるかもしれません。そのような場合は、ここで紹介する関数を使うとよいでしょう。なお、強制的にバッファの内容を出力するにはfflush関数を使用します。
バッファリングには、次の3つの方法があります。
- unbufferedはバッファリングを行わずに、すぐに出力します。
- fully bufferedは通常のバッファリングで、入出力データはバッファ経由で入出力します。
- line bufferedは新しい行が出力されるか、新しい行が入力されるまでバッファに溜め込みます。
14.12.1 setvbuf関数
setvbuf関数はバッファリング方法(バッファリング・モード)とバッファ領域を設定します。この関数はファイルオープン後で、入出力関数を呼び出す前に使用します。
【表14-1-35】 setvbuf関数
形式 | #include <stdio.h>
int setvbuf(FILE *fp, char *buf, int mode, size_t size); |
返り値 | 正常に処理ができた場合は0を返します。エラーの場合は0以外を返します。 |
引数 |
- FILE *fp
- 入力または、出力するファイルのファイルポインタを指定します。
- char *buf
- バッファ領域を指定します。バッファ領域は第4引数のsize以上の容量が必要です。なお、NULLを指定するとシステムで用意したバッファを使用します。
- int mode
- バッファリング方法(バッファリング・モード)を、次の値で指定します。
- _IONBF
- unbufferedです。
- _IOFBF
- fully bufferedです。
- _IOLBF
- line bufferedです。
- size_t size
- バッファの大きさを指定します。第2引数にNULLを指定した場合は0を指定します。
|
14.12.2 setbuf関数
setbuf関数はバッファ領域を設定します。
【表14-1-36】 setbuf関数
形式 | #include <stdio.h>
void setbuf(FILE *fp, char *buf); |
返り値 | ありません。 |
引数 |
- FILE *fp
- 入力または、出力するファイルのファイルポインタを指定します。
- char *buf
- バッファ領域を指定します。
|
14.12.3 例題
実行時引数として2つのファイルパス名を指定して、ファイルのコピーを行います。入力ファイルに対してはバッファ領域を指定し、出力ファイルに対してはバッファリングを行わない指定をしています。なお、ソースファイルの行数を少なくしてプログラムのポイントを明確にするため、エラー処理は省略しています。
#include <stdio.h>
#define IOB_SIZE 4096
#define LINE_SIZE 1024
int main(int argc, char **argv)
{
FILE *fp_src; /* コピー元ファイル */
FILE *fp_dest; /* コピー先ファイル */
char src_iobuff[IOB_SIZE]; /* コピー元IOバッファ */
char line[LINE_SIZE];
fp_src = fopen(*(argv + 1), "r");
setvbuf(fp_src, src_iobuff, _IOFBF, IOB_SIZE);
fp_dest = fopen(*(argv + 2), "w");
setvbuf(fp_dest, (char *)NULL, _IONBF, 0);
while(fgets(line, LINE_SIZE, fp_src) != NULL)
{
fputs(line, fp_dest);
}
fclose(fp_dest);
fclose(fp_src);
return 0;
}
$ cat /etc/issue ← catコマンドで/etc/issueファイルの内容を確認します
Fedora release 8 (Werewolf)
Kernel \r on an \m
$ ./ex14_1_11.prg /etc/issue ./temp.txt ← 実行時引数に/etc/issue指定して実行します
$ cat ./temp.txt
Fedora release 8 (Werewolf)
Kernel \r on an \m
$
- 2行目
- バッファ領域の大きさをIOB_SIZEというマクロ名で宣言します。
- 9行目
- バッファ領域として使用する配列を宣言します。容量は4096バイトです。
- 13行目
- 入力ファイル用のバッファ領域として、9行目で宣言しているsrc_iobuffを指定します。バッファリング・モードはfully bufferedです。
- 16行目
- 出力ファイルはバッファリングをしない指定をします。(バッファリング・モードはunbufferedです)