更改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
调用的 ExpandoObject
s。我正在寻找建议,以便以最简单的方式完成这项工作。
this commit 似乎增加了写 ExpandoObject
的能力。
请注意,这不在最新的 nuget 版本中(截至撰写本文时为 2.16.3),而是在下一个 3.x 版本中。如果您可以选择从 github 获取最新的测试版并使用它。
如果这样做,请注意您必须在每个 WriteRecord
之后调用 NextRecord
。在 2.16.3 中,CVSHelper 会为您调用它,所以这是一个突破性的 API 更改
假设我有一个大的 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
调用的 ExpandoObject
s。我正在寻找建议,以便以最简单的方式完成这项工作。
this commit 似乎增加了写 ExpandoObject
的能力。
请注意,这不在最新的 nuget 版本中(截至撰写本文时为 2.16.3),而是在下一个 3.x 版本中。如果您可以选择从 github 获取最新的测试版并使用它。
如果这样做,请注意您必须在每个 WriteRecord
之后调用 NextRecord
。在 2.16.3 中,CVSHelper 会为您调用它,所以这是一个突破性的 API 更改