Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何完全加载文件并处理记录csvreader?_C#_Csvhelper - Fatal编程技术网

C# 如何完全加载文件并处理记录csvreader?

C# 如何完全加载文件并处理记录csvreader?,c#,csvhelper,C#,Csvhelper,我使用CSV阅读器,发现解析数据需要很多时间。如何将整个csv文件加载到内存中,然后逐个记录地处理它,因为我必须对记录进行自定义映射 TextReader tr = new StreamReader(File.Open(@"C:\MarketData\" + symbol + ".txt", FileMode.Open)); CsvReader csvr = new CsvReader(tr); while (csvr.Read()) { // do your magic } 创建

我使用CSV阅读器,发现解析数据需要很多时间。如何将整个csv文件加载到内存中,然后逐个记录地处理它,因为我必须对记录进行自定义映射

  TextReader tr = new StreamReader(File.Open(@"C:\MarketData\" + symbol + ".txt", FileMode.Open));
  CsvReader csvr = new CsvReader(tr);
  while (csvr.Read())
{
// do your magic
}

创建一个准确表示/镜像CSV文件的类。然后将所有内容读入该类的列表中。以下剪报来自CsvHelper的文档

var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>().ToList();
var csv=新的CsvReader(文本阅读器);
var records=csv.GetRecords().ToList();
重要的部分是.ToList(),因为这将强制将所有数据加载到列表中,而不是在访问它们时生成结果

然后,您可以对该列表执行额外的映射/提取,该列表将保存在内存中


如果您已经这样做了,则可以通过(ToHashSet())将csv加载到哈希集中,而不是列表中。请参见创建准确表示/镜像CSV文件的类。然后将所有内容读入该类的列表中。以下剪报来自CsvHelper的文档

var csv = new CsvReader( textReader );
var records = csv.GetRecords<MyClass>().ToList();
var csv=新的CsvReader(文本阅读器);
var records=csv.GetRecords().ToList();
重要的部分是.ToList(),因为这将强制将所有数据加载到列表中,而不是在访问它们时生成结果

然后,您可以对该列表执行额外的映射/提取,该列表将保存在内存中


如果您已经这样做了,则可以通过(ToHashSet())将csv加载到哈希集中,而不是列表中。请参见

直接回答您的问题:您可以将文件完全加载到内存流中,然后使用CsvReader从该流中重新读取。类似地,您可以为您的filestream创建一个更大的读取缓冲区,例如15MB,它可以一次性将整个文件读取到缓冲区中。我怀疑这两种方法中的任何一种都会提高10MB文件的性能

找到真正的性能瓶颈:从磁盘读取文件内容的时间、将CSV解析为字段的时间,还是处理记录的时间?10MB的文件看起来非常小。我正在使用定制的csv阅读器处理250MB+csv文件集,没有任何抱怨

如果处理是瓶颈,并且您有多个可用线程,并且您的csv文件格式不需要支持转义换行符,那么您可以将整个文件读入行列表(System.IO.file.ReadAllLines/.ReadLines),并使用不同的任务解析每一行。例如:

System.IO.File.ReadLines()
.Skip(1)                  // header line. Assume trusted to be correct.
.AsParallel()
.Select(ParseRecord)      // RecordClass ParseRecord(string line)
.ForAll(ProcessRecord);   // void ProcessRecord(RecordClass)
如果有许多文件要解析,可以在不同的任务中处理每个文件,并使用异步方法最大限度地提高吞吐量。如果它们都来自同一个物理磁盘,那么您的差异将有所不同,甚至可能比单线程方法更糟

更高级:

如果您知道您的文件只包含8位字符,那么您可以对字节数组进行操作,并跳过StreamReader的开销,将字节转换为字符。这样,您可以在一次调用中将整个文件读入字节数组,并在不需要支持换行转义的情况下扫描换行符。在这种情况下,可以由多个线程扫描换行符,每个线程都查看字节数组的一部分

如果您不需要支持字段转义(a,“b,c”,d),那么您可以编写一个更快的解析器,只需查找字段分隔符(通常是逗号)。如果这是一个瓶颈,您还可以将字段划分解析和字段内容解析拆分为线程,尽管内存访问局部性可能会抵消任何好处


在某些情况下,您可能不需要将字段解析为中间数据结构(例如双精度、字符串)并且可以直接处理对字段开始/结束的引用,并保存一些中间数据结构创建。

直接回答您的问题:您可以将文件完全加载到内存流中,然后使用CsvReader从该流中重新读取。类似地,您可以为您的filestream创建一个更大的读取缓冲区,例如15MB,它可以一次性将整个文件读取到缓冲区中。我怀疑这两种方法中的任何一种都会提高10MB文件的性能

找到真正的性能瓶颈:从磁盘读取文件内容的时间、将CSV解析为字段的时间,还是处理记录的时间?10MB的文件看起来非常小。我正在使用定制的csv阅读器处理250MB+csv文件集,没有任何抱怨

如果处理是瓶颈,并且您有多个可用线程,并且您的csv文件格式不需要支持转义换行符,那么您可以将整个文件读入行列表(System.IO.file.ReadAllLines/.ReadLines),并使用不同的任务解析每一行。例如:

System.IO.File.ReadLines()
.Skip(1)                  // header line. Assume trusted to be correct.
.AsParallel()
.Select(ParseRecord)      // RecordClass ParseRecord(string line)
.ForAll(ProcessRecord);   // void ProcessRecord(RecordClass)
如果有许多文件要解析,可以在不同的任务中处理每个文件,并使用异步方法最大限度地提高吞吐量。如果它们都来自同一个物理磁盘,那么您的差异将有所不同,甚至可能比单线程方法更糟

更高级:

如果您知道您的文件只包含8位字符,那么您可以对字节数组进行操作,并跳过StreamReader的开销,将字节转换为字符。这样,您可以在一次调用中将整个文件读入字节数组,并在不需要支持换行转义的情况下扫描换行符。在这种情况下,可以由多个线程扫描换行符,每个线程都查看字节数组的一部分

如果您不需要支持字段转义(a,“b,c”,d),那么您可以编写一个更快的解析器,只需查找字段分隔符(通常是逗号)。如果这是一个瓶颈,您还可以将字段划分解析和字段内容解析拆分为线程,尽管内存访问局部性可能会抵消任何好处

在某些情况下,您可能不需要将字段解析为中间数据结构(例如双精度、字符串),可以直接处理对字段开头/结尾的引用,并保存一些中间数据结构的创建。

Well.NET streams