1

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


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

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

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

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

是否有不涉及逐行读取或将文件拆分为块的选项?此操作必须非常快。

4

4 回答 4

5

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

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

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

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

于 2013-11-02T17:42:16.147 回答
3

我投票结束您的问题,因为您的前提不正确。但是,如果这是一个真正的问题,没有什么可以阻止您编写自己的Skip扩展方法,该方法采用 along而不是 a 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)

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

于 2013-11-02T17:53:01.680 回答
2

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

于 2013-11-02T17:43:29.260 回答
1

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

于 2013-11-02T21:49:59.313 回答