如何阅读这个大文本文件?内存映射文件?

时间:2012-08-03 23:51:59

标签: c# performance memory file-io

我正处于一个简单工具的设计阶段,我想写一些我需要读取大型日志文件的工具。为了给你们一些背景信息,我先向你解释一下。

我需要读取的日志文件包含日志条目,这些日志条目总是包含以下3行格式:

statistics : <some data which is more of less of the same length about 100 chars>
request :  <some xml string which can be small (10KB) or big (25MB) and anything in between>
response :  <ditto>

日志文件大小约为100-600MB,这意味着大量日志条目。现在这些日志条目可以相互关联,为此我需要从头到尾开始读取文件。这些关系可以从统计线中推断出来。

我想使用统计信息行中的信息来构建一些数据网格,用户可以使用这些数据网格搜索数据并执行一些过滤操作。现在我不想将请求/响应行加载到内存中,直到用户真正需要它为止。另外,我想通过限制加载的请求/响应条目的最大值来保持较小的内存负载。

所以当我第一次解析文件并创建统计索引时,我认为我需要保存统计信息行的偏移量。然后,当用户单击某个统计信息时,该统计信息是日志条目的元素,然后我使用此偏移量从文件中读取请求/响应。然后我可以保留一些内存池,注意没有多少加载的请求/响应条目(参见前面的req)。

问题是我不知道用户多久需要一个请求/响应数据。这可能是很多次。此外,可以从网络共享加载日志文件。

我的问题是:

  1. 这是一个应该使用内存映射文件的情况,因为可能有很多读取操作吗?或者使用普通文件流更好。 BTW。在这个阶段我不需要对日志文件进行写操作,但它可能在将来!
  2. 如果您有其他提示或看到我的想法到目前为止的缺陷,请告诉我。我愿意接受任何方法。

    更新

    澄清更多内容:

    • 当用户从驱动器或网络共享加载日志文件时,工具本身必须进行解析。

    • 该工具将被编写为WinForms应用程序。

    • 用户可以导出精选的日志条目。此时此导出的格式未知(二进制文件,文件db,文本文件)。此导出可以由应用程序本身导入,然后仅显示用户所做的选择。

3 个答案:

答案 0 :(得分:1)

你在谈论一些在实际条目之间有一些已定义关系的存储数据......也许它只是我,但这个场景只需要某种关系型数据库。我建议考虑一些可移植的数据库,例如SQL Server CE。它将使您的生活更轻松,并提供您所需的功能。如果您使用db,则可以准确查询所需的数据,而无需处理大型文件。

答案 1 :(得分:1)

如果您通过网络发送请求/响应块,网络send()时间可能比seek()/ read()和使用memmap之间的差异大得多,这无关紧要。要真正实现这种扩展,一个简单的解决方案就是将文件分解为多个文件,每个文件对应一个要服务的块(因为“请求”最多可达25 MB)。然后您的HTTP服务器将尽可能有效地发送该块(甚至可能使用zerocopy,具体取决于您的Web服务器)。如果你有许多小的“请求”块,只有少数巨大的块,你可以只突破超过某个阈值的块。

答案 2 :(得分:0)

我不同意沃尔特的回答。我会去db或所有内存。

为什么你如此关注节省内存,因为600 MB并不是那么多。你打算在内存少于2 GB的机器上运行吗?

将统计信息作为键加载到字典中,并将值加载到具有两个属性的类 - 请求和响应。字典很快。 LINQ强大而快速。