编辑: @Everyone抱歉,我觉得与int32的大小混淆了。问题可能已经结束,但由于已有几个答案,我选择了第一个答案。 原始问题在下面供参考
我正在寻找一种从非常大的文本文件加载特定行的方法,我正在计划使用File.ReadLines和Skip()方法:
File.ReadLines(fileName).Skip(nbLines).Take(1).ToArray();
问题是,Skip()
取int
值,而int值限制在200万左右。应该适用于大多数文件,但是如果文件包含的内容,比如2000万行?我尝试使用long,但没有重载Skip()接受longs。
行是可变的,未知的长度,所以我不能计算字节数。
是否有一个选项不涉及逐行阅读或将文件拆分成块?此操作必须非常快。
答案 0 :(得分:5)
整数是32位数字,因此限制为2 十亿左右。
也就是说,如果你必须从文件中读取一个随机行,而你所知道的是文件中有行,你必须逐行读取它,直到你到达你想要的行。您可以使用一些缓冲区来稍微缓解I / O(默认情况下它们处于打开状态),但是您不会获得比这更好的性能。
除非,否则您将更改文件的保存方式。如果您可以创建一个索引文件,包含主文件的每一行的位置,您可以更快地读取一行。
嗯,不是无限的,但是很多更快 - 从O(N)到几乎O(1)(差不多,因为寻找文件中的随机字节可能不是O( 1)操作,取决于操作系统的操作方式。)
答案 1 :(得分: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)
没有问题(明年再来......)。多田!
答案 2 :(得分:2)
Int值限制在2 10亿而不是200万。因此,除非你的文件将超过大约2.4 十亿行,否则你应该没问题。
答案 3 :(得分:1)
您始终可以使用SkipWhile
和TakeWhile
,并编写自己的谓词