ディスク書き込みキャッシュをフラッシュする
-
05-07-2019 - |
質問
Windows XPおよびVistaのディスクのポリシーがハードディスクの書き込みキャッシュを有効にするように設定されている場合、書き込まれたばかりのファイルをフラッシュし、ディスクにコミットされたことを確認する方法はありますか?
C ++でプログラムでこれを行いたい。
ファイルを閉じると、アプリケーションレベルでフラッシュが実行されますが、オペレーティングシステムレベルでは実行されません。ファイルを閉じた後、オペレーティングシステムがディスク書き込みキャッシュをフラッシュする前にPCの電源が切断された場合、ファイルは閉じられていても失われます。
解決
開発環境を指定していないので、
.Net
IOストリームには、必要な処理を行う .Flush
メソッドがあります。
Win32 API
FlushFileBuffers
呼び出しがあり、引数としてファイルハンドルを取ります。
EDIT(OAからのコメントに基づく):FlushFileBuffersは管理者特権を必要としません。渡されるハンドルが単一のファイルではなくボリュームのハンドルである場合にのみ行われます。
他のヒント
.NET FileStream.Flush()は、そのファイルコンテンツのWindowsキャッシュをフラッシュしません。 Flush()は、.NET内部ファイルバッファのみをフラッシュします。 .NET 4.0では、MicrosoftはFlush()にオプションのパラメーターを追加して問題を修正しました。trueに設定すると、FlushFileSystemBuffersが呼び出されます。 .NET 3.5以前では、Pinvokeを介してFlushFileBuffersを呼び出すことが唯一の選択肢です。これを行う方法については、MSDNの FileStream.Flush コミュニティコメントを参照してください。 。
ファイルを閉じるときにこれを修正しないでください。ファイルを開いて FILE_FLAG_WRITE_THROUGH
をCreateFile()に渡さない限り、Windowsはキャッシュします。
FILE_FLAG_NO_BUFFERING
を渡すこともできます。これは、キャッシュにバイトのコピーを保持しないようにWindowsに指示します。
MSDNのCreateFileドキュメントによると、これはFlushFileBuffers()よりも効率的です。
ファイルバッファリングも参照してください。 MSDNのファイルキャッシュ。
>また、フレームワークAPIのフラッシュメソッドを呼び出しても、データが実際のディスクにフラッシュされない場合があることに注意してください。
flushメソッドを呼び出しても、カーネルにページをディスクにフラッシュするように指示するだけです。ただし、ディスクの書き込みキャッシュを有効にしている場合、実際の書き込みプロセスを無期限に遅らせることができます。
データが物理層に確実に書き込まれるようにするには、オペレーティングシステムの書き込みキャッシュをオフにする必要があります。これは、多くの場合、多くの小さなio操作を処理するときに最大1桁または2桁のパフォーマンスの低下を伴います。 バッテリーベースのサポート(UPS)またはディスク書き込みキャッシュをフラッシュするコマンドを受け入れるディスクは、この問題に対処する別のオプションです。
Microsoftのドキュメントでは、 _flushall およびCOMMODE.OBJにリンクして、すべてのバッファがディスクにコミットされたことを確認します。