CloseHandleを使わない場合
1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
2:WriteFileで開いたファイルにデータを書込みます。
3:ReadFileで読み込んだ内容が空白のままです。
CloseHandleを使う場合
1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
2:WriteFileで開いたファイルにデータを書込みます。
3:CloseHandleでファイルをいったん閉じます。
4:CreateFileで再オープンします。
5:ReadFileでちゃんと手順2で書き込んだデータを読み込めます。
これはなぜでしょうか?
> CloseHandleを使わない場合
> 1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
> 2:WriteFileで開いたファイルにデータを書込みます。
> 3:ReadFileで読み込んだ内容が空白のままです。
実は…つい最近やったコトがあります。
原因は簡単なコトで、ファイルポインタの位置がファイルの終端にいるから…です。
というコトで、SetFilePointer()で先頭に戻して下さい。
WriteFile の一番最初の引数は HANDLE ではありませんか?
そのハンドルを CloseHandle してみてください。
CloseHandle していないので、ReadFile で失敗しているかもしれません。
確認してみてください。
fopen の場合も fclose しないとデータが更新されないと思います。
ためしてみてください。
キャッシュが効いているためだと思われます。
一般的にディスクアクセスには時間がかかるため、システムは WriteFile が呼ばれた時
点で即座にディスクに書き込むことは行わず、そのデータを一時バッファにためておき
ます。
一定時間が経過したりバッファがいっぱいになると、実際にディスクへの書き込みが行
われます(これを「バッファをフラッシュする」と言います)。
CloseHandle や FlushFileBuffers 関数を使うと、明示的にバッファをフラッシュする
ことができます。
WriteFile で書き込んだデータは実際にはキャッシュ中に置かれていて、ReadFile でフ
ァイルを読もうとしてもまだファイルには書き込まれていないため読めないのではない
でしょうか。
ファイルを開くときに FILE_FLAG_NO_BUFFERING フラグを指定すれば解決するかもしれ
ません。パフォーマンスは低下しますが。
ReadFile、WriteFile、CloseHandle、FlushFileBuffers 等の解説を見てみましたが、こ
のように読み取れないという記述は見つかりませんでした。
どなたか、確かなところをご存じないでしょうか?
#キャッシュから読んでくれないと困るんだけどね。
あ、ごめんなさい。
CloseHandle を使用したくないんでしたね。
早とちりしました。ごめんなさい。。
瀬戸っぷさん>
ぬあ、それかっ!
恥ずかしいー(/・ω・\)
#include <windows.h>
#include <iostream>
#include <cstring>
#include <cassert>
int main() {
HANDLE hFile = CreateFile(trial.data, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert( hFile != INVALID_HANDLE_VALUE );
char buffer[4096];
std::strcpy(buffer, 適当な文字列を書き込み、再び読む);
DWORD size;
BOOL result;
result = WriteFile(hFile, buffer, std::strlen(buffer), &size, NULL);
assert( result );
result = FlushFileBuffers(hFile);
assert( result );
size = SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
assert( size == 0 );
buffer[0] = '\0';
result = ReadFile(hFile, buffer, 4096, &size, NULL);
assert ( result );
buffer[size] = '\0';
std::cout << buffer << std::endl;
return 0;
}
書いてすぐ読めてますよん。
1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
2:WriteFileで開いたファイルに関連するバッファにデータを書込みます。
3:FlushFileBuffersでバッファ内のデータをファイルに書き込みます。
4:SetFilePointerでファイルポインタを先頭に戻します。
5:ReadFileでちゃんと手順2で書き込んだデータを読み込めます
これで、解決しました。
ありがとうございました。
要は FlushFileBuffers/SetFilePointer をサボってた、てことですか?
解決したのに、解決済みをチェックし忘れたです。
> 要は FlushFileBuffers/SetFilePointer をサボってた、てことですか?
FlushFileBuffers/SetFilePointer をサボってたというよりは、この2つの関数をまった
く知らなかったです。
CloseHandleを使って、読み込めるようにさせるのはちょっといやだったので、
皆様に聞いたわけです。
やっぱりFlushFileBuffers/SetFilePointer を使って、気持ちよくなってきました。
ありがとう。