WinAPIで「ftell()」と「feof()」を再現する

 なぜか、Windouwsの標準APIには「ftell()」・「feof()」に対応するものが無い…。

ただ、他の関数を幾つか組み合わせればソレっぽい機能は実装できるので、メモっておこうかと。



ftell()

要するに、「現在のファイルポインタの位置」がわかればいい。

なので、至極単純にReadFile()の第四引数に返ってくる値を累積するなり、

SetFilePointer()で指定した値を与える等した変数を用意すればいい。


DWORD g_now_file_pos = 0;

DWORD FTell()
{
return g_now_file_pos;
}

...

DWORD FRead( void *buffer, DWORD size, DWORD num, HANDLE fp )
{
DWORD read_size = 0;
ReadFile( fp, buffer, size * num, &read_size, NULL );

// 読んだ分だけ進める
g_now_file_pos += read_size;
return read_size;
}

...

DWORD FSeek( HANDLE fp, long offset, int origin )
{
SetFilePointer( fp, offset, NULL, origin );

// 基準位置に合わせてポインタを移動
switch( origin )
{
case FILE_BEGIN:
g_now_file_pos = offset;
break;
case FILE_CURRENT:
g_now_file_pos += offset;
break;
case FILE_END:
g_now_file_pos = GetFileSize( fp, NULL ) +offset;
break;
}
}

 適当に関数にまとめるとこんな感じですかね。

…正直な所微妙なので、使う時に専用の変数を宣言して、

その変数に対して該当の操作をした方がいいと思う。

※(一応、注意する点としては、

ReadFile()の上記の値はfread()の戻り値と必ず等しくなるとは限らない*1ので、

もし標準の関数から移植をするなどするときは気をつけた方がいいかも)





feof()

 要するに、「ファイルの終端か」がわかればいいので、

上記のftell()に値するものと、GetFileSize()で得られる値を比較すればいい。


int Feof( HANDLE fp, DWORD now_pos )
{
if( now_pos >= GetFileSize( fp, NULL ) )
{
return -1;
}
return 0;
}




 一応、なるべくC標準関数からそのままの形で使えるように例を書いてみましたが、

…このままコピペだと使い辛いと思うので、使う際は自分である程度加工して使いましょう(苦笑)

*1:ReadFile()の方は「読み出したサイズ」fread()のほうは「読み出した個数