【问题标题】:Reading a specific line from a huge text file (c# 4.0)从巨大的文本文件中读取特定行(c# 4.0)
【发布时间】:2013-11-13 17:18:37
【问题描述】:

编辑: @Everyone对不起,我觉得混​​淆int32的大小很傻。问题可以关闭,但由于已经有几个答案,我选择了第一个。 原始问题如下供参考


我正在寻找一种从非常大的文本文件中加载特定行的方法,我正计划使用 File.ReadLines 和 Skip() 方法:

File.ReadLines(fileName).Skip(nbLines).Take(1).ToArray();

问题是,Skip()int 值,而 int 值限制在 200 万左右。对于大多数文件应该没问题,但是如果文件包含 2000 万行怎么办?我尝试使用 long,但 Skip() 的重载不接受 long。

行是可变的,长度未知,所以我无法计算字节数。

是否有不涉及逐行读取或将文件分成块的选项?这个操作一定很快。

【问题讨论】:

  • 旁注:阅读2000万行文本不可能“非常快”。我认为你写什么代码来跳过行并不重要,因为大部分时间都花在从磁盘读取......
  • 这个问题似乎跑题了,因为这个问题的前提是有缺陷的。 Int32 达到 20 亿左右。
  • Linq 也有方法ElementAtOrDefault,它试图在序列中找到Nth 条目。但是N 仍然是int (Int32)。您可以编写自己的扩展方法,它是 long (Int64)。
  • @Alexei 你是对的。我测试了多达 400k 行的文件,性能还可以接受,但 2000 万行引入了太多的延迟——猜想是时候放弃暴力解决方案了。

标签: c# io large-files


【解决方案1】:

整数是 32 位数字,因此限制在 2 十亿 左右。

也就是说,如果您必须从文件中随机读取一行,而您只知道该文件有行,则您必须逐行读取它,直到到达您想要的行。您可以使用一些缓冲区来稍微减轻 I/O 的负担(默认情况下它们处于打开状态),但您不会获得比这更好的性能。

除非您更改文件的保存方式。如果你可以创建一个索引文件,包含主文件每一行的位置,你可以无限快地读取一行。

嗯,不是无限的,而是 很多 更快 - 从 O(N) 到几乎 O(1)(几乎,因为在文件中寻找随机字节可能不是 O( 1) 操作,取决于操作系统如何操作)。

【讨论】:

    【解决方案2】:

    Int 值限制在 20 亿 左右,而不是 200 万。因此,除非您的文件将有超过 24 亿行,否则应该没问题。

    【讨论】:

      【解决方案3】:

      我投票结束您的问题,因为您的前提不正确。但是,如果这是一个真正的问题,没有什么可以阻止您编写自己的 Skip 扩展方法,该方法采用 long 而不是 int

      public static class SkipEx
      {
          public static IEnumerable<T> LongSkip<T>(this IEnumerable<T> src, 
                                                   long numToSkip)
          {
              long counter = 0L;
              foreach(var item in src)
              {
                  if(counter++ < numToSkip)continue;
                  yield return item;
              }
          }
      }
      

      所以现在你可以做这样的疯狂了

      File.GetLines(filename).LongSkip(100000000000L)
      

      没有问题(明年再来......)。多田!

      【讨论】:

        【解决方案4】:

        您始终可以使用SkipWhileTakeWhile,并编写自己的谓词

        【讨论】:

        • 谢谢。不知道。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-03
        • 2011-12-31
        • 2011-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多