ファイルに書き込んだ内容を即時に読み込めません – プログラミング – Home

ファイルに書き込んだ内容を即時に読み込...
 
通知
すべてクリア

[解決済] ファイルに書き込んだ内容を即時に読み込めません


佐倉
 佐倉
(@佐倉)
ゲスト
結合: 21年前
投稿: 43
Topic starter  

CloseHandleを使わない場合
1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
2:WriteFileで開いたファイルにデータを書込みます。
3:ReadFileで読み込んだ内容が空白のままです。

CloseHandleを使う場合
1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
2:WriteFileで開いたファイルにデータを書込みます。
3:CloseHandleでファイルをいったん閉じます。
4:CreateFileで再オープンします。
5:ReadFileでちゃんと手順2で書き込んだデータを読み込めます。

これはなぜでしょうか?


引用未解決
トピックタグ
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

> CloseHandleを使わない場合
> 1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
> 2:WriteFileで開いたファイルにデータを書込みます。
> 3:ReadFileで読み込んだ内容が空白のままです。

実は…つい最近やったコトがあります。
原因は簡単なコトで、ファイルポインタの位置がファイルの終端にいるから…です。
というコトで、SetFilePointer()で先頭に戻して下さい。


返信引用
ゆう
 ゆう
(@ゆう)
ゲスト
結合: 23年前
投稿: 114
 

WriteFile の一番最初の引数は HANDLE ではありませんか?
そのハンドルを CloseHandle してみてください。
CloseHandle していないので、ReadFile で失敗しているかもしれません。
確認してみてください。

fopen の場合も fclose しないとデータが更新されないと思います。
ためしてみてください。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

キャッシュが効いているためだと思われます。

一般的にディスクアクセスには時間がかかるため、システムは WriteFile が呼ばれた時
点で即座にディスクに書き込むことは行わず、そのデータを一時バッファにためておき
ます。
一定時間が経過したりバッファがいっぱいになると、実際にディスクへの書き込みが行
われます(これを「バッファをフラッシュする」と言います)。
CloseHandle や FlushFileBuffers 関数を使うと、明示的にバッファをフラッシュする
ことができます。

WriteFile で書き込んだデータは実際にはキャッシュ中に置かれていて、ReadFile でフ
ァイルを読もうとしてもまだファイルには書き込まれていないため読めないのではない
でしょうか。
ファイルを開くときに FILE_FLAG_NO_BUFFERING フラグを指定すれば解決するかもしれ
ません。パフォーマンスは低下しますが。

ReadFile、WriteFile、CloseHandle、FlushFileBuffers 等の解説を見てみましたが、こ
のように読み取れないという記述は見つかりませんでした。
どなたか、確かなところをご存じないでしょうか?

#キャッシュから読んでくれないと困るんだけどね。


返信引用
ゆう
 ゆう
(@ゆう)
ゲスト
結合: 23年前
投稿: 114
 

あ、ごめんなさい。
CloseHandle を使用したくないんでしたね。
早とちりしました。ごめんなさい。。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

瀬戸っぷさん>
ぬあ、それかっ!
恥ずかしいー(/・ω・\)


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 600
 

#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;
}

書いてすぐ読めてますよん。


返信引用
佐倉
 佐倉
(@佐倉)
ゲスト
結合: 21年前
投稿: 43
Topic starter  

1:CreateFileで既存するファイルを開きます。ファイルの中身は空です。
2:WriteFileで開いたファイルに関連するバッファにデータを書込みます。
3:FlushFileBuffersでバッファ内のデータをファイルに書き込みます。
4:SetFilePointerでファイルポインタを先頭に戻します。
5:ReadFileでちゃんと手順2で書き込んだデータを読み込めます

これで、解決しました。
ありがとうございました。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 600
 

要は FlushFileBuffers/SetFilePointer をサボってた、てことですか?


返信引用
佐倉
 佐倉
(@佐倉)
ゲスト
結合: 21年前
投稿: 43
Topic starter  

解決したのに、解決済みをチェックし忘れたです。


返信引用
佐倉
 佐倉
(@佐倉)
ゲスト
結合: 21年前
投稿: 43
Topic starter  

> 要は FlushFileBuffers/SetFilePointer をサボってた、てことですか?
FlushFileBuffers/SetFilePointer をサボってたというよりは、この2つの関数をまった
く知らなかったです。
CloseHandleを使って、読み込めるようにさせるのはちょっといやだったので、
皆様に聞いたわけです。
やっぱりFlushFileBuffers/SetFilePointer を使って、気持ちよくなってきました。
ありがとう。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました