【发布时间】:2018-12-10 20:29:47
【问题描述】:
问题:有没有办法使用 MemoryMappedViewStream 读取超过 2GB 的文件?
我正在尝试读取 1 到 12 GB 的日志文件。 1GB 文件读取正常,但读取 4GB 文件时收到以下错误:
System.IO.IOException HResult=0x80070008 消息=不够 存储可用于处理此命令。
Source=System.Core StackTrace:在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
在 System.IO.MemoryMappedFiles.MemoryMappedView.CreateView(SafeMemoryMappedFileHandle memMappedFileHandle,MemoryMappedFileAccess 访问,Int64 偏移量, Int64 大小)在 System.IO.MemoryMappedFiles.MemoryMappedFile.CreateViewStream(Int64 偏移量,Int64 大小,MemoryMappedFileAccess 访问)在 System.IO.MemoryMappedFiles.MemoryMappedFile.CreateViewStream() 在 ExchIISParserLib.LogParser.ParseLogs(Int32 天前) 在 ...
我的系统有足够的磁盘和内存空间来读取 4GB 文件。有问题的代码行是:
MemoryMappedViewStream memoryMappedViewStream = MemoryMappedFile.CreateFromFile(log, FileMode.Open).CreateViewStream();
在我的研究工作中,我发现当文件超过 2GB 时,MemoryMappedViewStream 似乎会出现问题。
https://stackoverflow.com/a/49738895/4630376
我查看了CreateViewStream() 方法的偏移量和大小参数。但那些似乎只是在指定文件上创建一个静态窗口,它不会读取整个文件。
【问题讨论】:
-
可能是一个愚蠢的问题,但是(如您发布的链接中所述),您不是在运行 32 位进程吗?
-
@user1074069 不,我已经将它编译为 64 位。
-
为什么在 64 位模式下也存在这个限制有点神秘,我还没有看到令人信服的解释。可能是架构上的限制,但我强烈怀疑微软留下这个是为了阻止程序员犯这个大错误。通过创建此视图,您将 RAM 需求翻倍。文件已经被设计为内存映射,文件系统缓存会处理它。再做一次是个坏主意,尤其是对于如此巨大的视野。映射视图所需的 RAM 将从文件系统缓存使用的 RAM 中取出,实际上使其效率大大降低。
-
@HansPassant 好的,但我该如何解决呢?解决这个问题的最有效方法是什么?如果您知道答案,请提供。否则,您知道我可以使用的在线教程吗?
-
很简单,扔掉一堆代码。使用 FileStream 或 StreamReader,他们知道如何在没有任何帮助的情况下使用文件系统缓存。设置系统要求不会受到伤害,如果你经常使用 FileStream.Seek(),你会想要 32GB 的 RAM。如果你只使用顺序访问,那就不用担心了。