【问题标题】:Unable to read large log file with MemoryMappedViewStream无法使用 MemoryMappedViewStream 读取大型日志文件
【发布时间】: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。如果你只使用顺序访问,那就不用担心了。

标签: c# memory


【解决方案1】:

内存映射视图流是内存映射视图上的流。它不提供整个文件的流,而只是您映射的部分。您仍然需要分块映射文件以读取整个内容。除非您真的需要共享内存,否则您最好还是分块读取文件。

【讨论】:

  • 知道我会怎么做吗?我习惯于通过 SSIS 连接管理器读取大文件,它抽象了文件的读取。在这种情况下,我不能这样做,因为文件包含不同长度的记录(我正在将文件解析为 SSIS 连接管理器可以使用的东西)。
  • 除非您真的需要自己编写代码,否则我可能会使用另一个日志文件解析器工具(如 MSFT logparser.exe)来执行此操作。它提供了使用类似 SQL 的语法查询日志的能力,并且已经很好地处理了大文件。如果您仍然想编写代码,那么我们需要更多关于您在解析日志时想要做什么的信息(例如您正在搜索/过滤的数据的结构和类型),以便任何人为您提供代码满足您的需求。
  • 这似乎是一个间歇性问题。我可以按照 Hans 的建议使用 StreamReader。我继续并将其标记为已回答,因为您提供了一些有用的信息。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 1970-01-01
  • 2018-11-09
相关资源
最近更新 更多