使用 FileHelpers 将动态 CSV 读取到 DataTable
Using FileHelpers to read a dynamic CSV to DataTable
我发现 FileHelpers 处理 "rich" CSV 非常方便,具有自定义分隔符、带引号的标识符、空项过滤等。
但它似乎主要是为了加载预先已知格式的文件,以创建一个强类型的 object 列表,其属性装饰有应该与 headers.
匹配的属性。
我的目的有点不同:
我希望能够加载自定义 CSV 文件,其格式和列数事先未知,采用灵活的格式,如 DataTable 或某种字符串数组。旁注:我的 csv 来自 Stream,而不是物理文件。
我做了一些尝试,使用 FileHelperEngine
中的 ReadStreamAsDT
之类的方法(下面的完整实现),但我遇到了一些问题。
- 如果 header 包含空格或其他不能出现在 C# 属性中的字符,它会抛出异常“
The string 'My field' not is a valid .NET identifier
”。我的 header 可以包含所有类型的字符。
- 需要单独手动解析header行
我的实现存在上述问题:
using (var streamReader = new StreamReader(stream, true))
{
var cb = new DelimitedClassBuilder("temp", ";")
{
IgnoreFirstLines = 0,
IgnoreEmptyLines = true,
Delimiter = ";"
};
var headerArray = streamReader.ReadLine().Split(';');
foreach (var header in headerArray)
{
cb.AddField(header, typeof(string));
cb.LastField.FieldQuoted = true;
cb.LastField.QuoteChar = '"';
}
var engineType = cb.CreateRecordClass();
var engine = new FileHelperEngine(engineType);
var datatable = engine.ReadStreamAsDT(streamReader);
}
我想避免导入另一个 CSV 包而不是 FileHelpers,并且由于我们稍后还需要使用相同的逻辑生成一些 CSV,所以我想避免为此编写自己的代码。
FileHelpers 文档对我使用 DataTable 帮助不大。
我也注意到 one-liner 方法,例如 CommonEngine.CsvToDataTable()
或 CsvEngine.CsvToDataTable()
,但它旨在从物理文件中工作。
有没有办法使用 FileHelpers 来利用一些高级功能(安全引用处理、修整、CSV 生成等)?
在我写问题的时候,我刚刚编写了自己的代码来将 CSV 文件加载到数据表中,其中包含我需要的所有功能。
然而,还有一个库比 FileHelpers 在这个领域做得更好,“CsvHelper”:https://joshclose.github.io/CsvHelper/:
https://joshclose.github.io/CsvHelper/examples/data-table/
using (var reader = new StreamReader("path\to\file.csv"))
using (var csv = new CsvReader(reader))
{
// Do any configuration to `CsvReader` before creating CsvDataReader.
using (var dr = new CsvDataReader(csv))
{
var dt = new DataTable();
dt.Load(dr);
}
}
(如果需要自定义,只需设置分隔符等)
如果您愿意,也可以手动完成:
https://github.com/JoshClose/CsvHelper/issues/1142#issuecomment-432910368 如果你愿意的话。
我发现 FileHelpers 处理 "rich" CSV 非常方便,具有自定义分隔符、带引号的标识符、空项过滤等。 但它似乎主要是为了加载预先已知格式的文件,以创建一个强类型的 object 列表,其属性装饰有应该与 headers.
匹配的属性。我的目的有点不同: 我希望能够加载自定义 CSV 文件,其格式和列数事先未知,采用灵活的格式,如 DataTable 或某种字符串数组。旁注:我的 csv 来自 Stream,而不是物理文件。
我做了一些尝试,使用 FileHelperEngine
中的 ReadStreamAsDT
之类的方法(下面的完整实现),但我遇到了一些问题。
- 如果 header 包含空格或其他不能出现在 C# 属性中的字符,它会抛出异常“
The string 'My field' not is a valid .NET identifier
”。我的 header 可以包含所有类型的字符。 - 需要单独手动解析header行
我的实现存在上述问题:
using (var streamReader = new StreamReader(stream, true))
{
var cb = new DelimitedClassBuilder("temp", ";")
{
IgnoreFirstLines = 0,
IgnoreEmptyLines = true,
Delimiter = ";"
};
var headerArray = streamReader.ReadLine().Split(';');
foreach (var header in headerArray)
{
cb.AddField(header, typeof(string));
cb.LastField.FieldQuoted = true;
cb.LastField.QuoteChar = '"';
}
var engineType = cb.CreateRecordClass();
var engine = new FileHelperEngine(engineType);
var datatable = engine.ReadStreamAsDT(streamReader);
}
我想避免导入另一个 CSV 包而不是 FileHelpers,并且由于我们稍后还需要使用相同的逻辑生成一些 CSV,所以我想避免为此编写自己的代码。
FileHelpers 文档对我使用 DataTable 帮助不大。
我也注意到 one-liner 方法,例如 CommonEngine.CsvToDataTable()
或 CsvEngine.CsvToDataTable()
,但它旨在从物理文件中工作。
有没有办法使用 FileHelpers 来利用一些高级功能(安全引用处理、修整、CSV 生成等)?
在我写问题的时候,我刚刚编写了自己的代码来将 CSV 文件加载到数据表中,其中包含我需要的所有功能。
然而,还有一个库比 FileHelpers 在这个领域做得更好,“CsvHelper”:https://joshclose.github.io/CsvHelper/: https://joshclose.github.io/CsvHelper/examples/data-table/
using (var reader = new StreamReader("path\to\file.csv"))
using (var csv = new CsvReader(reader))
{
// Do any configuration to `CsvReader` before creating CsvDataReader.
using (var dr = new CsvDataReader(csv))
{
var dt = new DataTable();
dt.Load(dr);
}
}
(如果需要自定义,只需设置分隔符等)
如果您愿意,也可以手动完成: https://github.com/JoshClose/CsvHelper/issues/1142#issuecomment-432910368 如果你愿意的话。