如果我正在尝试确定驱动器的读取速度,我可以编写例程来将文件写入文件系统,然后再读取这些文件。不幸的是,由于Windows执行磁盘读取缓存,因此无法提供准确的读取速度。

有没有办法在C#/ .Net(或者可能使用Win32 API调用)中刷新驱动器的磁盘读取缓存,这样我就可以直接从驱动器读取文件而不将它们缓存?

有帮助吗?

解决方案

为何选择DIY?

如果您只需确定驱动器速度并且对学习如何从.NET刷新I / O缓冲区不感兴趣,您可以使用 http://research.microsoft.com/barc/Sequential_IO/ 。它具有随机/顺序模式,有或没有缓冲区刷新。

该页面还有一些您可能会觉得有用的与I / O相关的研究报告。

其他提示

康斯坦丁:谢谢!该链接有一个命令行EXE,它执行我正在寻找的测试。

我还在此页面上找到了一个链接,指向此页面上更有趣的文章(Word和PDF格式):顺序文件编程模式和.NET性能

在本文中,它讨论了未缓冲的文件性能(低,没有读/写缓存 - 只是原始磁盘性能。)

直接引用文章:

  

没有简单的禁用方法   V2 .NET中的FileStream缓冲   框架。必须调用Windows   文件系统直接获取   未缓冲的文件句柄然后   ‘包裹’ 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构造函数的参数   表示该流应该采取   文件句柄的所有权,意思是   文件句柄会   当自动关闭   流已关闭。在这之后   hocus-pocus,未缓冲的文件   流被读取和写入相同   和其他人一样。

Fix的响应几乎正确且优于PInvoke。 但它有错误并且不起作用......

要打开没有缓存的文件,需要执行以下操作:

const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;

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

几条规则:

  1. blockSize必须是硬盘驱动器群集大小对齐(大多数时间为4096)
  2. 文件位置更改必须是群集大小对齐
  3. 你不能读/写少于blockSize或阻止不对齐它的大小
  4. 不要忘记 - 还有硬盘缓存(比缓存更慢,更小),你无法关闭它(但有时FileOptions.WriteThrough有助于不缓存写入)。使用这些选项,您没有理由进行刷新,但请确保您已经正确测试了这种方法在缓存执行速度较慢的情况下不会减慢速度。

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);

我发现这篇文章,似乎这个是一个复杂的程序,因为你还必须刷新其他缓存。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top