我必须解析大的CSV文件并提高吞吐量我使用异步和等待。我当前的方法是逐行读取文件并执行我自己的解析:
using (var streamReader = File.OpenText(fileName))
{
string line;
while ((line = await streamReader.ReadLineAsync()) != null)
{
// Parse line ...
}
}
然而,正确解析CSV文件并不容易,例如当字符串包含逗号等时。
我一直无法找到兼容性和支持异步和等待的CSV解析器。如何在不编写解析器的情况下使用异步I / O有效地解析CSV文件?
答案 0 :(得分:2)
您可以查看非常有用且易于使用的CsvHelper library(也可用作NuGet package)。这甚至包括内置的mapping功能,可将CSV记录映射到对象。
CSV Helper用于读取和写入CSV文件的.NET库。极其快速,灵活且易于使用。支持阅读和写作 自定义类对象。
它不是异步的(如在async/await
中),但是如评论中所建议的那样,您可以围绕它创建自己的异步包装。
答案 1 :(得分:1)
我是CsvHelper的推荐。这是我用来异步加载CSV文件集合的类。它确实等待数据在返回之前被读取:
public CsvParser()
{
Task[] LoadData = new Task[3]
{
Task.Factory.StartNew(
() =>
{
IEnumerable<MachineDetail> Machines = GetCsvContents<MachineDetail>("MachineDetail*.csv");
this.MachineData.AddRange(Machines);
}
),
Task.Factory.StartNew(
() =>
{
IEnumerable<SiteDetail> Sites = GetCsvContents<SiteDetail>("SiteDetail*.csv");
this.SiteData.AddRange(Sites);
}
),
Task.Factory.StartNew(
() =>
{
IEnumerable<KeyDetail> Keys = GetCsvContents<KeyDetail>("_keysheets_*.csv");
this.KeyData.AddRange(Keys);
}
)
};
Task.WaitAll(LoadData);
}
private List<T> GetCsvContents<T>(string CsvFileName)
{
List<T> ReturnContents = new List<T>();
FileInfo[] CsvFiles = ResourceDirectory.GetFiles(CsvFileName, SearchOption.TopDirectoryOnly);
foreach (FileInfo CsvFile in CsvFiles)
{
using (CsvReader ReadCsv = new CsvReader(new StreamReader(CsvFile.FullName)))
{
ReturnContents.AddRange(ReadCsv.GetRecords<T>());
}
}
return ReturnContents;
}