我有一个非常大的CSV文件,大约有1,000,000行,它需要大约500 MB的内存。我不必阅读所有文件。我想从文件中读取每百分之一行。我试图通过ReadLines
来做,但它确实很慢,ReadAllLines
更快。
我的代码:
for (int i = 0; i < 10000; i++)
{
tableOfString[i]=File.ReadLines("TestCSV.csv").Skip(i*100).Take(1).First();
//or
tableOfString[i] = File.ReadLines("TestCSV.csv").ElementAtOrDefault(i*100);
}
我读到了一些读者:
有人有解决方案吗?我想只读取CSV中的某些行,而不是整个文件。
答案 0 :(得分:2)
ReadLines
并不慢。问题是您要在每次迭代中将文件重新读取到所需的行 。 (当i = 1时,你读0-100行...当i = 2时,你读0-200行等等。)
您应该避免多次调用File.ReadLines
。换句话说,只打开文件一次并使用Where
过滤掉您不想要的行。所以试试这个:
var filteredLines = File.ReadLines("TestCSV.csv")
.Select((Text, Index) => new {Text, Index})
.Where(x => x.Index % 100 == 0);
foreach(var line in filteredLines)
{
tableOfString[line.Index] = line.Text;
}
不确定你是如何创建或使用tableOfString
的,但是如果它仅用于获取这些行,那么你可以直接将你的linq查询转换为数组(你不必填充) for循环中的数组:
var tableOfString = File.ReadLines("TestCSV.csv")
.Where((x, i) => i % 100 == 0)
.ToArray();
答案 1 :(得分:1)
根据您想要的代码
CSV文件的 0th, 100th, 200th ... 1000000th
行并将其存储在tableOfString[]
你可以这样做:
tableOfString = File
.ReadLines("TestCSV.csv")
.Where((line, index) => (index % 100) == 0)
.ToArray();
在循环中重新打开文件(速度很慢)意味着很大的开销
答案 2 :(得分:0)
首先,如果您不想将完整文件加载到内存中,则File.ReadLines和File.ReadAllLines不起作用。
如果您只想将文件的几个字节读入RAM,我建议您使用File.OpenRead
,然后将所需的部分读入缓冲区。与How can I read/stream a file without loading the entire file into memory?一样。
但是,除了你有问题,你不能跳过99行,只读每100行。如果要实现此功能,则需要知道每行的大小,以便在读取方法中设置偏移量。
最新版本是使用File.ReadAllLine
,而不是迭代字符串数组或使用Linq。