C 言語 | 高度な機能 | ランダムアクセス - fseek(), ftell()
ファイルの先頭から順番にデータを読み書きする方法をシーケンシャルアクセスと呼ぶ。任意の位置へ移動し、必要な部分だけを読み書きする方法をランダムアクセスと呼ぶ。ここでは標準 C 関数を使ったランダムアクセスを説明する。
任意の位置から読み込む
通常のファイル入力は、先頭から末尾へ順番に進む。データを読み込むと、次の操作位置は自動的に進む。次に読み書きするバイト位置をファイル位置と呼ぶ。
通常のテキストデータにはシーケンシャルアクセスが効率的である。しかし、バイナリーファイルには異なる種類の情報が 1 つのファイルに連続して保存されることが多い。特定のバイト位置にある値だけが必要な場合、手前のデータをすべて読み込むのは効率的ではない。
ファイル位置を移動するには fseek() を使用する。
fseek() 関数
int fseek(FILE *stream, long offset, int origin);
stream には有効なファイルストリーム、offset には origin から移動するバイト数を指定する。
| 定数 | 意味 |
|---|---|
SEEK_CUR |
現在のファイル位置 |
SEEK_SET |
ファイルの先頭 |
SEEK_END |
ファイルの末尾 |
fseek() は成功すると 0、失敗すると 0 以外を返す。
現在のファイル位置を取得するには ftell() を使用する。
ftell() 関数
long ftell(FILE *stream);
コード 1
#include <stdio.h>
int main() {
char fileName[256];
int fileIndex , text;
FILE *file;
printf("読み込むファイル名を指定してください>");
scanf("%s" , fileName);
printf("読み込み開始位置をバイト単位で指定してください。");
scanf("%d" , &fileIndex);
file = fopen(fileName , "rb");
if (file == NULL) {
fprintf(stderr , "ファイル操作でエラーが発生しました。\n");
return 0;
}
fseek(file , fileIndex , SEEK_SET);
printf("ファイル位置 %ld から読み込みます--\n" , ftell(file));
while(1) {
text = fgetc(file);
if (feof(file)) break;
printf("%c" , text);
}
printf("\n");
fclose(file);
return 0;
}
このプログラムはファイル名と読み込み開始位置を受け取る。SEEK_SET を指定し、ファイルの先頭から fileIndex バイト進んだ位置へ移動した後、残りのデータを文字として表示する。ランダムアクセスは、特にバイナリーデータを扱う場合に役立つ。