【问题标题】:Changing a csv file, reading and writing with dynamic mapping更改 csv 文件,使用动态映射进行读写
【发布时间】:2016-12-02 22:52:29
【问题描述】:

假设我有一个大的 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 作用于单个 记录而不是调用作用于 a 的 GetRecords 或 WriteRecords 记录清单?

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

发生的情况是GetRecord 返回一个ExpandoObject,然后WriteRecord 阻塞了这个对象。

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

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

【问题讨论】:

  • 错误告诉您使用 GetRecords(复数)而不是单数。我的意思是它在暗示它。你试过了吗?
  • @CodingYoshi,不,这不是我需要的。
  • 看看 Mar L 的回答 here 看看是否对你有帮助。
  • @CodingYoshi,谢谢,不,它没有。答案建议不要使用 CSVHelper。我需要 CSVHelper 因为这是一个不平凡的 CSV 文件。它有带引号的字段,一些带引号的字段是多行的,等等。CSVHelper 非常适合解析此文件并将其写回,只要我们能解决这个缺陷。
  • 如果您所做的只是更改 CSV 特征(如刻度等)而不是数据,那么您不能只读取原始字段(未键入)

标签: c# .net csvhelper


【解决方案1】:

this commit 中似乎添加了编写ExpandoObject 的功能。

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

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

【讨论】:

  • 旧版本给我CsvConfigurationException: 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?,新版本(3.0)给我CsvTypeConverterException: Converting IEnumerable types is not supported for a single field. If you want to do this, create your own ITypeConverter and register it in the TypeConverterFactory by calling AddConverter.
猜你喜欢
  • 2014-06-19
  • 2021-02-08
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多