【问题标题】:c# how to grep through ~300mb log file quickly时间:2019-05-10 标签:c#how to grep through ~300mb log file fast
【发布时间】:2012-10-05 03:49:22
【问题描述】:

我试图在 C# 中读取一个非常大的日志文件 - 大约 300mbs 的原始文本数据。我已经在大约 1mb 的较小文件上测试我的程序,它将所有日志消息存储到 string[] 数组中并使用 contains 进行搜索。

但是这太慢了,占用了太多内存,我永远无法处理 300mb 的日志文件。我需要一种 gr​​ep 文件的方法,它可以快速过滤它以找到有用的数据并打印与搜索相对应的日志信息行。

最大的问题是规模,我认为 300mb 将是我的最大值,但需要我的程序来处理它。我可以使用哪些函数、数据结构、搜索来以速度和效率很好地扩展来读取这么大的日志文件

【问题讨论】:

  • 我确信会有一些方法可以更快地运行 grep,但是在你这样做之前,你是否能够在 grep 之前通过更快的字符串比较检查来预过滤日志?
  • 您是在使用 grep 还是正在编写一个程序来这样做?您可以考虑逐行处理而不是读取整个文件。一个更复杂但独立于行长的操作是您一次读取一定数量的字符并处理它(虽然实现起来很棘手)。
  • 如果可以使用 .NET 4,请参阅this question 推荐 StreamReader 或 MemoryMappedFile。
  • 您是否测量了最耗时的内容?是读取文件吗?搜索?垃圾收集?
  • 日志文件太大了,我想读取文件,搜索我正在寻找的标签。我想在命中时显示并忽略其他情况。我将它们存储在列表框视图(数组)中。我必须找到一种更好的方法来将信息写入不使用太多内存的 c#,因为我认为列表框本质上是一个数组

标签: c# arrays file grep


【解决方案1】:

File.ReadLines 可能是您最好的选择,因为它会为您提供文本文件行的IEnumerable,并在您遍历IEnumerable 时懒惰地读取它们。然后,您可以使用任何方法来搜索您想要使用的行(RegexContains 等)并对其进行处理。我下面的示例生成了一个线程来搜索该行并将其输出到控制台,但您几乎可以做任何事情。当然,TEST、TEST、TEST 对大文件看你的性能里程。我想如果下面生成的每个单独的线程花费的时间太长,你可能会遇到线程限制。

IEnumerable<string> lines = File.ReadLines("myLargeFile.txt");
foreach (string line in lines) {
    string lineInt = line;
    (new Thread(() => {
        if (lineInt.Contains(keyword)) {
            Console.WriteLine(lineInt);
        }
    })).Start();
}

编辑:通过我自己的测试,这显然更快:

foreach (string lineInt in File.ReadLines("myLargeFile.txt").Where(lineInt => lineInt.Contains(keyword))) {
    Console.WriteLine(lineInt);
}

【讨论】:

  • Sumo,所以 File.ReadLines() 不会一次将整个文件读入内存?
  • 不,它只是给你一个迭代器,当你迭代 IEnumerable 时,它​​会从文件中产生一行。
  • 是的,我认为我的大问题是将它们全部存储在数组中,即使我不必这样做。我只是希望能够搜索到我想要的东西,然后将重要信息存储在内存中
  • @JonathanHenson 如果您正在实现自己的 IO,这可能是正确的。在这种情况下,您只是在 System.IO 中使用 .NET 4 框架的一项功能,该功能为您提供了一种处理几乎任何大小文件的简单方法。只有通过测试才能证明它对您的表现如何。
  • +1。特别是用于测试和测量。显然,每行显示一个线程纯粹是为了娱乐,实际上创建多个线程(尤其是这里无限数量的线程)会影响几乎所有任务的性能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 2020-10-01
  • 2015-06-14
  • 2011-07-08
相关资源
最近更新 更多