如果我正在尝试确定驱动器的读取速度,我可以编写例程来将文件写入文件系统,然后再读取这些文件。不幸的是,由于Windows执行磁盘读取缓存,因此无法提供准确的读取速度。
有没有办法在C#/ .Net(或者可能使用Win32 API调用)中刷新驱动器的磁盘读取缓存,这样我就可以直接从驱动器读取文件而不将它们缓存?
答案 0 :(得分:13)
康斯坦丁:谢谢!该链接有一个命令行EXE,它执行我正在寻找的测试。
我还在此页面上找到了一个链接,指向此页面上更有趣的文章(Word和PDF格式):Sequential File Programming Patterns and Performance with .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,未缓冲的文件 流被读取和写入相同 和其他人一样。
答案 1 :(得分:11)
Fix的响应几乎正确且优于PInvoke。 但它有错误并且不起作用......
要打开没有缓存的文件,需要执行以下操作:
const FileOptions FileFlagNoBuffering = (FileOptions)0x20000000;
FileStream file = new FileStream(fileName, fileMode, fileAccess, fileShare, blockSize,
FileFlagNoBuffering | FileOptions.WriteThrough | fileOptions);
几条规则:
并且不要忘记 - 还有硬盘缓存(比缓存更慢和更小),你无法关闭它(但有时FileOptions.WriteThrough有助于不缓存写入)。使用这些选项,您没有理由进行刷新,但请确保您已经正确测试了这种方法在缓存执行速度较慢的情况下不会减慢速度。
答案 2 :(得分:4)
为何选择DIY?
如果您只需确定驱动器速度并且对学习如何从.NET刷新I / O缓冲区不感兴趣,您可以使用http://research.microsoft.com/barc/Sequential_IO/中的DiskSpd实用程序。它具有随机/顺序模式,有或没有缓冲区刷新。
该页面还有一些您可能会觉得有用的与I / O相关的研究报告。
答案 3 :(得分: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);
答案 4 :(得分:0)
我发现了this文章,看起来这是一个复杂的程序,因为你还需要刷新其他缓存。