Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.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# FileHelpers在解析大型csv文件时抛出OutOfMemoryException_C#_Csv_Filehelpers - Fatal编程技术网

C# FileHelpers在解析大型csv文件时抛出OutOfMemoryException

C# FileHelpers在解析大型csv文件时抛出OutOfMemoryException,c#,csv,filehelpers,C#,Csv,Filehelpers,我正试图用FileHelpers()解析一个非常大的csv文件。该文件压缩为1GB,解压为20GB string fileName = @"c:\myfile.csv.gz"; using (var fileStream = File.OpenRead(fileName)) { using (GZipStream gzipStream = new GZipStream(fileStream, CompressionMode.

我正试图用FileHelpers()解析一个非常大的csv文件。该文件压缩为1GB,解压为20GB

        string fileName = @"c:\myfile.csv.gz";
        using (var fileStream = File.OpenRead(fileName))
        {
            using (GZipStream gzipStream = new GZipStream(fileStream, CompressionMode.Decompress, false))
            {
                using (TextReader textReader = new StreamReader(gzipStream))
                {
                    var engine = new FileHelperEngine<CSVItem>();
                    CSVItem[] items = engine.ReadStream(textReader);                        
                }
            }
        }
stringfilename=@“c:\myfile.csv.gz”;
使用(var fileStream=File.OpenRead(文件名))
{
使用(GZipStream GZipStream=newgzipstream(fileStream,CompressionMode.decompresse,false))
{
使用(TextReader TextReader=newstreamReader(gzipStream))
{
var engine=new FileHelperEngine();
CSVItem[]items=engine.ReadStream(textReader);
}
}
}
然后FileHelpers抛出OutOfMemoryException

测试失败:“System.OutOfMemoryException”类型的异常为 扔。System.OutOfMemoryException:类型为的异常 已引发“System.OutOfMemoryException”。在 System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)位于 System.Text.StringBuilder.Append(字符值,Int32 repeatCount)位于 System.Text.StringBuilder.Append(字符值)位于 FileHelpers.StringHelper.ExtractQuotedString(LineInfo行,字符 quoteChar,布尔allowMultiline)在 FileHelpers.DelimitedField.ExtractFieldString(LineInfo行)位于 FileHelpers.FieldBase.ExtractValue(LineInfo行)位于 FileHelpers.RecordInfo.StringToRecord(LineInfo行)位于 FileHelpers.FileHelperEngine
1.ReadStream(文本阅读器,Int32
maxRecords,数据表dt)位于
FileHelpers.FileHelperEngine
1.ReadStream(文本阅读器)


可以用FileHelper解析这么大的文件吗?如果没有,谁能推荐一种方法来解析这么大的文件?谢谢。

这不是一个完整的答案,但是如果你有一个20GB的csv文件,你将需要20GB+来一次性将整个内容存储在内存中,除非你的阅读器将所有内容都压缩在内存中(不太可能)。您需要分块读取文件,如果没有大量ram,那么将所有内容放入阵列的解决方案将无法工作

您需要一个更像这样的循环:

CsvReader reader = new CsvReader(filePath)
CSVItem item = reader.ReadNextItem();
while(item != null){
  DoWhatINeedWithCsvRow(item);
  item = reader.ReadNextItem();
}
C#的内存管理将足够智能,可以在您浏览旧的Csvitem时处理它们,前提是您不保留对它们的引用


更好的版本是从CSV中读取一个区块(例如10000行),处理所有这些区块,然后获取另一个区块,或者为DoWhatINeedWithCsvRow创建一个任务,如果您不关心处理顺序的话。

您必须以这种方式逐个记录地工作:

  string fileName = @"c:\myfile.csv.gz";
  using (var fileStream = File.OpenRead(fileName))
  {
      using (GZipStream gzipStream = new GZipStream(fileStream, CompressionMode.Decompress, false))
      {
          using (TextReader textReader = new StreamReader(gzipStream))
          {
            var engine = new FileHelperAsyncEngine<CSVItem>();
            using(engine.BeginReadStream(textReader))
            {
                foreach(var record in engine)
                {
                   // Work with each item
                }
            }
          }
      }
  }
stringfilename=@“c:\myfile.csv.gz”;
使用(var fileStream=File.OpenRead(文件名))
{
使用(GZipStream GZipStream=newgzipstream(fileStream,CompressionMode.decompresse,false))
{
使用(TextReader TextReader=newstreamReader(gzipStream))
{
var engine=new FileHelperAsyncEngine();
使用(engine.BeginReadStream(文本阅读器))
{
foreach(发动机中的var记录)
{
//处理每个项目
}
}
}
}
}

如果使用这种异步方法,一次只能使用一条记录的内存,速度会快得多。

BowserKingKoopa我的第一个问题很明显,解压文件时有多少可用空间如果是20GB,我会加倍,看看是否有40GB的空闲空间。是否要将~20GB的数据放入RAM?真的吗?你不应该用二进制阅读器而不是文本阅读器吗?FileHelper是否处理缓冲区大小,或者您是否需要自己设置缓冲区大小?在我看来,这是您应该使用数据库处理的事情(因此实际数据将保留在HD上)。。。例如,为什么不创建sqlite数据库并将该CSV导入到表中呢?谢谢!FileHelperAsyncEngine正是我想要的。