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

7
假设我有一个大型的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);
        }
    }
}

以下是运行时出现的错误:

继承IEnumerable的类型无法自动映射。您是否意外调用了GetRecord或WriteRecord,这些方法作用于单个记录,而不是调用GetRecords或WriteRecords,这些方法作用于记录列表?

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

问题在于GetRecord返回一个ExpandoObject,然后WriteRecord在此对象上出现问题。

最好的解决方法是什么?

更新: 只是为了明确:我完全意识到之所以会出现这个错误是因为CSVHelper不支持ExpandoObject用于WriteRecord调用。 我正在寻找建议,以便最简单地解决此问题。


@CodingYoshi,不对,这不是我需要的。 - Andrew Savinykh
看看马尔L在这里的答案(https://dev59.com/plwX5IYBdhLWcg3w2iku),看看那是否能帮到你。 - CodingYoshi
@CodingYoshi,谢谢,答案建议不要使用CSVHelper。我需要CSVHelper,因为这是一个非平凡的CSV文件。它有带引号的字段,一些带引号的字段是多行的,等等。如果我们能克服这个缺陷,CSVHelper就非常适合解析这个文件并将其写回。 - Andrew Savinykh
如果你只是改变CSV的特性(如ticks等),而不是数据,那么你可以直接读取原始字段(未经类型化)。 - Ňɏssa Pøngjǣrdenlarp
@Plutonix,这解决了读取的部分,但我还需要手动格式化结果以进行写入。感谢您的建议。 - Andrew Savinykh
显示剩余4条评论
1个回答

4
看起来在这个提交中添加了写入ExpandoObject的能力。
请注意,这不是最新的nuget版本(在撰写本文时为2.16.3),而是针对接下来的3.x版本。如果您可以选择,请从github获取最新的beta版本并使用它。
如果您这样做,请注意每次WriteRecord后都必须调用NextRecord。在2.16.3 CVSHelper会为您调用它,因此这是一个破坏API更改。

1
旧版本给了我CsvConfigurationException: 继承IEnumerable的类型不能自动映射。您是否意外调用了GetRecord或WriteRecord,这些方法作用于单个记录,而不是调用GetRecords或WriteRecords,这些方法作用于记录列表?而新版本(3.0)给了我CsvTypeConverterException: 不支持转换IEnumerable类型为单个字段。如果您想要这样做,请创建自己的ITypeConverter并通过调用AddConverter将其注册到TypeConverterFactory中。 - Nikolay Kostov

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