以文本方式查看主题 - 计算机科学论坛 (http://bbs.xml.org.cn/index.asp) -- 『 C/C++编程思想 』 (http://bbs.xml.org.cn/list.asp?boardid=61) ---- C#直接读取磁盘文件(类似linux的Direct IO模式) (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=125046) |
-- 作者:卷积内核 -- 发布时间:6/6/2012 1:21:00 PM -- C#直接读取磁盘文件(类似linux的Direct IO模式) 1. 程序的要求 程序的要求很简单。 (1)命令行程序 (2)有3个参数,读取的文件名,一次读取buffer size,读取的次数count (3)如果读取次数count未到,文件已经读完,就再次从头读取文件。 使用格式如下: C:\>****.exe “c:\****.bin” 32768 32768 读取文件“c:\****.bin”,每次读取4K,读取32768次,读取的量大概1G。
2. 一般的FileStream方式 using System; namespace DirectIO if (args.Length < 3) try byte[] b = new byte[bs]; 基于上述情况,可以判断是缓存的原因,导致第二次及以后各次都比较快。 但是从代码中来看,已经执行了input.Flush();input.Close();甚至是GC.Collect(); 所以可能是Windows系统或者CLR对文件读取操作进行了优化,使用了缓存。
|
-- 作者:卷积内核 -- 发布时间:6/6/2012 1:22:00 PM -- 3. 利用kernel32.dll中的CreateFile函数 既然上述方法行不通,就得调查新的方法。通过google的查询,大部分人都是建议用C/C++调用系统API来实现。 不过最后终于找到了用c#实现了无缓存直接读取磁盘上的文件的方法。其实也是通过DllImport利用了kernel32.dll,不完全是托管代码。(估计用纯托管代码实现不了) 参考的文章:How do I read a disk directly with .Net? 还有msdn中的CreateFile API 实现代码就是参考的How do I read a disk directly with .Net?,分为两部分 (1)利用CreateFile API构造的可直接读取磁盘的DeviceStream using System; namespace DirectIO // Use interop to call the CreateFile function. [DllImport("kernel32.dll", SetLastError = true)] private SafeFileHandle handleValue = null; public DeviceStream(string device) private void Load(string Path) // Try to open the file. handleValue = new SafeFileHandle(ptr, true); // If the handle is invalid, public override bool CanRead public override bool CanSeek public override bool CanWrite public override void Flush() public override long Length public override long Position public override long Seek(long offset, SeekOrigin origin) public override void SetLength(long value) public override void Write(byte[] buffer, int offset, int count) public override void Close() new void Dispose() private new void Dispose(bool disposing) } } IntPtr ptr = CreateFile(Path, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, NO_BUFFERING, IntPtr.Zero); 之前没有加这个参数的时候,在xp上测试还是第二次比第一次快很多。
|
-- 作者:卷积内核 -- 发布时间:6/6/2012 1:22:00 PM -- (2)完成指定要求的DIOReader using System; namespace DirectIO if (args.Length < 3) try byte[] b = new byte[bs]; 这样,就完成了类似linux上Direct IO模式读取文件的操作。 通过这个例子可以看出,C#不仅可以开发上层的应用,也可以结合一些非托管的dll完成更加底层的操作。
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
116.943ms |