使用CsvHelper将CSV中的所有值读入List

Ayb*_*btu 19 c# csv csvhelper

所以我一直在阅读我不应该编写自己的CSV读写器,所以我一直在尝试使用通过nuget安装的CsvHelper库.CSV文件是灰度图像,行数是图像高度,数字列是宽度.我想将行值逐行读入单个List<string>List<byte>.

我到目前为止的代码是:

using CsvHelper;

public static List<string> ReadInCSV(string absolutePath)
{
    IEnumerable<string> allValues;

    using (TextReader fileReader = File.OpenText(absolutePath))
    {
        var csv = new CsvReader(fileReader);
        csv.Configuration.HasHeaderRecord = false;
        allValues = csv.GetRecords<string>
    }

    return allValues.ToList<string>();
}
Run Code Online (Sandbox Code Playgroud)

但是allValues.ToList<string>()扔了一个:

用户代码未处理CsvConfigurationException

CsvHelper.dll中出现"CsvHelper.Configuration.CsvConfigurationException"类型的异常,但未在用户代码中处理

附加信息:继承IEnumerable的类型无法自动映射.您是否意外调用了对单个记录执行操作的GetRecord或WriteRecord,而不是调用作为记录列表的GetRecords或WriteRecords?

GetRecords可能期望我自己的自定义类,但我只是想将值作为一些原始类型或字符串.此外,我怀疑整行正在转换为单个字符串,而不是每个值都是一个单独的字符串.

mas*_*ger 26

根据@Marc L'的帖子你可以试试这个:

public static List<string> ReadInCSV(string absolutePath) {
    List<string> result = new List<string>();
    string value;
    using (TextReader fileReader = File.OpenText(absolutePath)) {
        var csv = new CsvReader(fileReader);
        csv.Configuration.HasHeaderRecord = false;
        while (csv.Read()) {
           for(int i=0; csv.TryGetField<string>(i, out value); i++) {
                result.Add(value);
            }
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 由于 CsvReader 是 IDisposable,因此 ```var csv = new CsvReader(fileReader);``` 也应该在 using() 语句中吗?(可能还没到回答的时间) (3认同)

Jos*_*ose 15

如果您只需要数组中每行的字符串值,则可以直接使用解析器.

var parser = new CsvParser( textReader );
while( true )
{
    string[] row = parser.Read();
    if( row == null )
    {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

http://joshclose.github.io/CsvHelper/#reading-parsing

更新

版本3支持读取和编写IEnumerable属性.

  • 它将行分为基于RFC 4180的字段,有一些配置可以处理非标准文件,然后像Excel一样回退处理它.如果你的字段中有一个`\n`怎么办?`ReadAllLines()`会给你2行,当它只有1行时. (5认同)
  • 只是好奇:这是否真的给了你任何你用 File.ReadAllLines() 还没有得到的东西,证明添加另一个库依赖的成本是合理的?另外,`CsvParser` 不是`IDisposable` 吗? (2认同)

小智 5

这里的重点是读取 CSV 的所有行并将其反序列化为对象集合。我不知道为什么你想把它作为字符串的集合来读取。ReadAll()如前所述,在这种情况下,通用可能最适合您。当您将这个库用于此目的时,它就会大放异彩:

using System.Linq;

...
using (var reader = new StreamReader(path))
using (var csv = new CsvReader(reader))
{
    var yourList = csv.GetRecords<YourClass>().ToList();
}
Run Code Online (Sandbox Code Playgroud)

如果您不使用ToList()- 它将一次返回一条记录(为了更好的性能),请阅读https://joshclose.github.io/CsvHelper/examples/reading/enumerate-class-records