FILE_FLAG_NO_BUFFERINGで開かれたファイルの終わりをどのように記述しますか?
質問
VB6とWin32 APIを使用してファイルにデータを書き込みます。この機能はデータのエクスポート用です。したがって、ディスクへの書き込みパフォーマンスが考慮事項の重要な要素です。そのため、 CreateFile
を呼び出してファイルを開くときに、 FILE_FLAG_NO_BUFFERING
および FILE_FLAG_WRITE_THROUGH
オプションを使用しています。
FILE_FLAG_NO_BUFFERING
では、独自のバッファを使用して、ディスクのセクタサイズの倍数でファイルにデータを書き込む必要があります。これは、データの最後の部分を除いて、一般に問題ありませんセクターサイズの正確な倍数にはファイルの文字ゼロのパディングが含まれませんが、最後のブロックが書き込まれた後にこれらの文字ゼロを含まないようにファイルサイズを設定するにはどうすればよいですか?
SetEndOfFile
を使用できますが、これには FILE_FLAG_NO_BUFFERING
を使用せずにファイルを閉じて再度開く必要があります。私は誰かが NtSetInformationFile
について話しているのを見ましたが、VB6でこれを使用して宣言する方法を見つけることができません。 SetFileInformationByHandle
は私が望むことを正確に行うことができますが、Windows Vistaでのみ利用可能で、アプリケーションは以前のバージョンのWindowsと互換性が必要です。
解決
わかりませんが、FILE_FLAG_NO_BUFFERINGおよびFILE_FLAG_WRITE_THROUGHを設定するとパフォーマンスが最大になると確信していますか?
確かにできるだけ早くデータがディスクにヒットするようになりますが、そのようなことは実際にはパフォーマンスを向上させません-ジャーナルファイルなど、クラッシュのイベント。
説明したようなデータエクスポートルーチンの場合、オペレーティングシステムがデータをバッファリングできるようにすると、パフォーマンスが向上する可能性があります。書き込みごとにファイルします。
これらのオプションなしでコードをベンチマークしないのはなぜですか? 0バイトのパディングロジックのままにして、公平なテストにします。
これらのオプションをスキップする方が速いことが判明した場合は、0パディングロジックを削除して、ファイルサイズの問題を解決できます。
他のヒント
SetEndOfFileが唯一の方法だと思います。
そして、Mike Gに同意します。FILE_FLAG_NO_BUFFERINGを使用して、または使用せずにコードをベンチする必要があります。最新のOSでのWindowsファイルバッファリングは非常に効果的です。
まあ驚いた!自分ですべてを行う代わりにWindowsバッファリングを使用すると、かなり高速になります。私は自分のバッファーと FILE_FLAG_NO_BUFFERING
および FILE_FLAG_WRITE_THROUGH
オプションを使用して、テストのために1Gbファイルを書き出しましたが、これらの設定なしで、Windowsバッファーを使用して平均21.146秒かかりました平均時間が13.53秒に短縮され、30%以上高速になりました!
自己への注意:車輪を再発明する必要はありません。 ;-)
迅速かつ正確な回答をいただき、「マイクG 」に感謝します。また、「 gabr 」にも感謝します。今は SetEndOfFile
を使用する必要はまったくありません。
1 GBファイルの場合、Windowsのバッファリングはおそらく高速です。多数の小さなIOを実行する場合。使用可能なRAMよりもはるかに大きいファイルを処理し、ラージブロックIOを実行する場合、WILLを設定していたフラグはスループットを向上させる必要があります(スレッドの多い、またはランダムなラージブロックIOの場合、最大3倍高速)。