【问题标题】:Read chosen line from CSV从 CSV 读取所选行
【发布时间】:2014-10-28 09:27:59
【问题描述】:

我有一个非常大的 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 中读取某些行,而不是整个文件。

【问题讨论】:

  • 全部存储在一个字符串[]中,而不是使用File.ReadLines。您可以使用File.ReadAllLinesFile.ReadLines 返回一个 IQueryable,所以当你访问它时,你会查询所有行。
  • 你是说不想将整个文件读入内存?
  • File.ReadLines("TestCSV.csv").ElementAtOrDefault(i * 100);

标签: c# performance csv readline


【解决方案1】:

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();

【讨论】:

  • 这是一个很好的解决方案,但它仍然迭代文件中的所有行并且只占用它节省 RAM 的百分之一。 :) 是否可以不迭代所有内容而只采用这些选定的行?它会更快。现在我的文件有 500,000 行,我只需要 1000 行,但读取它仍然需要 2 秒。
【解决方案2】:

根据你想要得到的代码

0th, 100th, 200th ... 1000000th CSV 文件的行并将它们存储在tableOfString[]

你可以这样做:

  tableOfString = File
    .ReadLines("TestCSV.csv")
    .Where((line, index) => (index % 100) == 0)
    .ToArray();

在循环中重新打开文件(这很慢)意味着很大的开销

【讨论】:

    【解决方案3】:

    首先,如果您不想将完整的文件加载到内存中,则 File.ReadLines 和 File.ReadAllLines 不起作用。

    如果您只想将文件的几个字节读入 RAM,我建议您使用File.OpenRead,而不是将您需要的部分读入缓冲区。喜欢How can I read/stream a file without loading the entire file into memory?

    但是你有一个问题,你不能跳过 99 行,只能阅读每 100 行。如果你想实现这个,你需要知道每一行的大小来设置你在Read-Method中的偏移量。

    最简单的版本是使用File.ReadAllLine,而不是遍历字符串数组或使用Linq。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 2016-12-15
      • 1970-01-01
      • 2022-01-09
      相关资源
      最近更新 更多