2008-09-23 97 views
6

如果我試圖確定驅動器的讀取速度,我可以編寫一個例程來將文件寫入文件系統,然後再讀取這些文件。不幸的是,這並沒有給出準確的讀取速度,因爲Windows執行磁盤讀取緩存。如何在C#中清空/刷新Windows READ磁盤緩存?

有沒有辦法在C#/ .Net(或可能用Win32 API調用)中刷新驅動器的磁盤讀取緩存,以便我可以直接從驅動器讀取文件而不需要緩存?

回答

4

爲什麼選擇DIY?

如果您只需要確定驅動器速度,而不是真正有興趣學習如何從.NET中刷新I/O緩衝區,則可以使用http://research.microsoft.com/barc/Sequential_IO/的DiskSpd實用程序。它具有隨機/順序模式,有和沒有緩衝區沖洗。

該頁面還包含一些您可能會覺得有用的I/O相關研究報告。

0

我發現this文章,似乎這是一個複雜的程序,因爲你也必須刷新其他緩存。

12

Constantin:謝謝!該鏈接有一個命令行EXE,用於執行我正在尋找的測試。

我還發現過該網頁更有趣的文章,此頁面上的鏈接(在Word和PDF):Sequential File Programming Patterns and Performance with .NET

在這篇文章中,它談論無緩衝文件性能(督察,沒有讀/寫緩存 - 只是原始磁盤性能)

直接從文章引述:

有一個在V2 .NET框架 禁用 的FileStream緩衝沒有簡單的方法。必須直接調用視窗 文件系統以獲得 無緩衝文件句柄,然後 「渦卷」的結果在一個FileStream作爲 在C#如下:

[DllImport("kernel32", SetLastError=true)] 
    static extern unsafe SafeFileHandle CreateFile(
     string FileName,   // file name 
     uint DesiredAccess,  // access mode 
     uint ShareMode,   // share mode 
     IntPtr SecurityAttributes, // Security Attr 
     uint CreationDisposition, // how to create 
     uint FlagsAndAttributes, // file attributes 
     SafeFileHandle hTemplate // template file 
     ); 

    SafeFileHandle handle = CreateFile(FileName, 
          FileAccess.Read, 
          FileShare.None, 
          IntPtr.Zero, 
          FileMode.Open, 
          FILE_FLAG_NO_BUFFERING, 
          null); 

    FileStream stream = new FileStream(handle, 
        FileAccess.Read, 
        true, 
        4096); 

調用CreateFile()與 FILE_FLAG_NO_BUFFERING標誌告訴 文件系統繞過該文件的所有軟件 內存緩存。作爲第三 參數到FileStream構造 通過 「真」值指示流應該採取的文件句柄 所有權,這意味着 該文件句柄將 自動當 流關閉關閉。在此之後,非緩衝文件 流被以與其他任何其他方式相同的 方式讀取和寫入。

+0

我投票贊成,但測試後沒有奏效 - 不幸的是,這一點太晚了,不能移除我的投票!代碼無法編譯(無法通過`FileAccess.Read`和類似於`CreateFile()`的操作,並且如果您鍵入強制轉換枚舉代碼不運行 - 不能將`null`作爲hTemplate。 – Oliver 2016-01-15 14:28:16

3
const int FILE_FLAG_NO_BUFFERING = 0x20000000; 
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,64 * 1024, 
(FileOptions)FILE_FLAG_NO_BUFFERING | FileOptions.Asynchronous 
& FileOptions.SequentialScan); 
10

修復的反應幾乎是正確的,比PInvoke的更好。 但它有錯誤並且不起作用...

要打開文件W/O緩存一個需要做以下幾點:

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000; 

FileStream file = new FileStream(fileName, fileMode, fileAccess, fileShare, blockSize, 
    FileFlagNoBuffering | FileOptions.WriteThrough | fileOptions); 

一些規則:

  1. 塊大小必須是4096對準硬盤的簇大小(大部分時間)
  2. 文件位置更改必須是羣集大小對齊
  3. 您無法讀取/寫入較少的臨時文件ñ塊大小或阻止不對準它的大小

而且不要忘記 - 還有硬盤緩存(其中慢,比操作系統的緩存更小的),你可以不通過關閉(但有時FileOptions.WriteThrough有助於不緩存寫入)。有了這些選項,你就沒有理由刷新,但要確保你已經正確地測試過,這種方法不會減慢速度,以防你的緩存實現速度較慢。