在C#中高效读取CSV文件?

4

我正在以以下方式读取大型csv文件(每个文件约有350K行):

StreamReader readFile = new StreamReader(fi);
    string line;
    string[] row;
    readFile.ReadLine();
    while ((line = readFile.ReadLine()) != null)
    {
        row = line.Split(';');
        x=row[1];
        y=row[2];
        //More code and assignations here...
    }
    readFile.Close();
}

这里的重点是,每个月按行阅读一个巨大的文件可能会很慢,我认为必须有另一种更快的方法来处理它。


1
任何方法都必须读取整个文件。 - CodeCaster
5
可能是CSV parser/reader for C#?的重复问题。 - kayess
2
为了节省您的时间,上次我对ReadLine()循环、基于自定义缓冲区方法(该方法不创建字符串,而是将小的值类型偏移量大小对存储到缓冲区中)和ReadAllLines()进行了性能基准测试,结果ReadLine()循环表现最好。请专注于优化您的处理过程。 - Cameron
2
使用 SplitReadLine 解析 csv 时,要小心,因为如果数据中有引号内的分隔符或换行符,会读取不正确。使用类似 Microsoft.VisualBasic.FileIO.TextFieldParser 的工具会更安全。 - Andy Nichols
1
你能详细描述一下你的任务吗?你需要所有行还是仅基于某种 ID 列的特定行?你需要在 UI 上显示它并可以按页懒加载,还是需要处理整个文件? - alex.b
显示剩余2条评论
2个回答

25

方法1

通过使用LINQ:

var Lines = File.ReadLines("FilePath").Select(a => a.Split(';'));
var CSV = from line in Lines 
          select (line.Split(',')).ToArray();

方法2

正如Jay Riggs在此处所述:

这是一个出色的类,将使用数据结构复制CSV数据到DataTable中,从而创建DataTable:

用于平面文件的便携式高效通用解析器

它易于配置和使用。我建议您自行查看。

方法3

除非您读取的文件保证非常简单,否则自己编写CSV阅读器是浪费时间。相反,使用现有、经过试验和验证的实现


6
第一个操作是 File.ReadAllLines,它在使用 linq 之前将整个文件内容全部读入内存。 - gunr2171
@gunr2171 我已经改成了 ReadLines,因为 File.ReadLines() 返回的是一个 IEnumerable<string>,它不会一次性读取整个文件,所以在处理大型文件时确实是更好的选择。 - Vignesh Kumar A
1
方法三应该改为方法一。CSV文件很复杂! - jpaugh
1
方法1对于字符串内的'\n'(回车符)和/或';'(分号)无效。使用split解析csv在通用情况下不可行。 - mgueydan

9
在一个简单的情况下(文件中没有引号,即'"'),当你期望进行部分读取时,你可能会发现这很有用。
  var source = File
    .ReadLines(fileName)
    .Select(line => line.Split(';'));

例如,如果您想查找CSV中是否存在一行,使得第三列的值等于0
  var result = source
    .Any(items => items[2] == "0");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接