更改csv文件,使用动态映射读写

Changing a csv file, reading and writing with dynamic mapping

假设我有一个大的 csv 文件,我想读取、修改和写回。也许我想将字段分隔符从逗号更改为制表符。也许我想将引号字符从 ' 更改为 "。或者我想为第一列中的每个值添加一个加号。由于文件很大,我不想一次将它加载到内存中,我想一条条一条一条的看。

所以我写了这样的代码:

var inPath = @"infile.txt";
var outPath = @"outfile.txt";

CsvConfiguration readCf = GetReadConfiguration();
CsvConfiguration writeCf = GetWriteConfiguration();

using (var streamin = new FileStream(inPath, FileMode.Open))
using (var streamReader = new StreamReader(streamin))
{
    using (var csvReader = new CsvReader(streamReader, readCf))
    using (var csvWriter = new CsvWriter(new StreamWriter(outPath), writeCf))
    {
        while (csvReader.Read())
        {
            var currentRecord = csvReader.GetRecord<dynamic>();
            UpdateRecord(currentRecord);
            csvWriter.WriteRecord(currentRecord);
        }
    }
}

这在 运行 时失败并出现以下错误:

Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?

请注意,UpdateRecord 中没有发生任何有趣的事情,实际上上面的这一行可以完全注释掉。

发生的事情是 GetRecord returns 一个 ExpandoObject 然后 WriteRecord 在此对象上窒息。

完成这项工作的最佳方法是什么?

更新 很清楚:我完全意识到我收到此错误是因为 CSVHelper 不支持 WriteRecord 调用的 ExpandoObjects。我正在寻找建议,以便以最简单的方式完成这项工作。

this commit 似乎增加了写 ExpandoObject 的能力。

请注意,这不在最新的 nuget 版本中(截至撰写本文时为 2.16.3),而是在下一个 3.x 版本中。如果您可以选择从 github 获取最新的测试版并使用它。

如果这样做,请注意您必须在每个 WriteRecord 之后调用 NextRecord。在 2.16.3 中,CVSHelper 会为您调用它,所以这是一个突破性的 API 更改