【发布时间】: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 特征(如刻度等)而不是数据,那么您不能只读取原始字段(未键入)