2008-10-06 145 views
4

當Windows XP和Vista中的磁盤策略設置爲在硬盤上啓用寫入緩存時,是否有辦法刷新剛剛寫入的文件並確保它已被提交到磁盤?刷新磁盤寫入緩存

我想在C++中以編程方式執行此操作。

關閉文件確實在應用程序級別執行刷新,但不在操作系統級別執行刷新。如果關閉文件後但在操作系統刷新磁盤寫入緩存之前電源已從PC中移除,即使該文件已關閉,該文件也會丟失。

+0

你的意思是編程?這個問題沒有說清楚 – 2008-10-06 08:16:19

+0

我們假設你的問題是關於編程,但是你沒有指定開發環境。 – tzot 2008-10-06 08:41:29

回答

2

您還沒有指定的發展環境,因此:

IO流有一個.Flush方法你想要做什麼。

的Win32 API

還有就是FlushFileBuffers呼叫,這需要一個文件句柄作爲參數。

編輯(基於來自OA的評論):FlushFileBuffers不需要管理權限;它只有在傳遞給它的句柄是一個卷的句柄而不是單個文件的時候。

+0

看來,這將工作。不幸的是,應用程序必須能夠運行而不需要管理權限。 – selwyn 2008-10-06 11:24:08

+0

我找不到這個.NET方法。據我所見,框架使用FlushFileBuffers的唯一地方是在SerialStream中。我懷疑p /調用FlushFileBuffers是安全的。 – 2009-03-25 23:08:00

1

從微軟文檔你可以使用_flushall和COMMODE.OBJ鏈接來確保所有的緩衝區都被提交到磁盤。

2

您還應該注意,即使在調用框架API的flush方法時,您的數據也可能不會被刷新到實際的磁盤。

調用flush方法將只告訴內核將其頁面刷新到磁盤。但是,如果您打開了磁盤寫入緩存,則可以無限期地延遲實際的寫入過程。

爲了確保您的數據被寫入物理層,您必須打開操作系統中的寫入緩存。在處理大量小型io操作時,這通常會導致性能損失高達一個或兩個數量級。 基於電池的支持(UPS)或接受命令刷新磁盤寫入緩存的磁盤是解決此問題的另一個選項。

3

您在關閉文件時不應該修復此問題。 Windows將緩存,除非您打開通過FILE_FLAG_WRITE_THROUGH到CreateFile()的文件。

您可能還想通過FILE_FLAG_NO_BUFFERING;這告訴Windows不要在緩存中保留字節的副本。

根據MSDN上的CreateFile文檔,這比FlushFileBuffers()更高效。

另請參閱MSDN上的file bufferingfile caching

8

.NET FileStream.Flush()不會刷新該文件內容的Windows緩存; Flush()只刷新.NET內部文件緩衝區。在.NET 4.0中,Microsoft通過向Flush()添加可選參數來解決該問題,如果設置爲true,則會導致調用FlushFileSystemBuffers。在.NET 3.5及以下版本中,您唯一的選擇是通過pinvoke調用FlushFileBuffers。有關如何執行此操作,請參閱MSDN的FileStream.Flush社區評論。