CsvHelper的文件流和datagridview内存问题

问题描述

TL; DR

  • 在传递到CsvHelper进行正常处理之前(在流内),读取和修改内存中的平面文件
  • 在约32k的记录上进行测试时,过程运行良好,可以多次运行
  • 在5m +的记录上运行时,该过程只能运行一次,如果尝试再次运行,则该过程将失败
  • 引发System.OutOfMemoryException错误

链接到此帖: CsvHelper - Set the header row and data row

自从我提出了一个可能的解决方案之后,新的问题就与原始帖子有所不同。但是我现在面临另一个问题。

因此,我对测试样本数据进行了如下修改(我在第7行中添加一个管道):

This is a random line in the file

SOURCE_ID|NAME|START_DATE|END_DATE|VALUE_1|VALUE_2

Another random line in the file

|


GILBER|FRED|2019-JAN-01|2019-JAN-31|ABC|DEF
ALEF|ABC|2019-FEB-01|2019-AUG-31|FBC|DGF
GILBER|FRED|2019-JAN-01|2019-JAN-31|ABC|TEF
FLBER|RED|2019-JUN-01|2019-JUL-31|AJC|DEH
GI|JOE|2020-APR-01|2020-DEC-31|GBC|DER

我决定尝试处理内存中的入站文件,然后将该流传递给CsvHelper进行处理。

我最终得到了以下代码

// Using BufferdStream for speed
// https://stackoverflow.com/questions/2161895/reading-large-text-files-with-streams-in-c-sharp
// Read from memory stream
// https://stackoverflow.com/questions/1232443/writing-to-then-reading-from-a-memorystream

int header_row = 3; //row the header is on
int data_row = 10; //row the data starts from

using (FileStream fs = File.Open(filepath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (var stream = new MemoryStream())
using (StreamWriter sw = new StreamWriter(stream))
using (StreamReader sr = new StreamReader(bs))
{
    string line;
    int i = 0;
    while ((line = sr.ReadLine()) != null)
    {
        i++;
        if (i < header_row) // check if the line is less than the header row,if yes ignore
            continue;
        if (i > header_row && i < data_row) // check if the line is between the header row and start of the data,if yes ignore
            continue;
        
        {
            // write to stream if all conditions pass
            sw.WriteLine(line);
            sw.Flush();
        }
        
    }

    sw.Flush();
    stream.Position = 0; //reset position

    // continue using CsvHelper as before,Feeding in the 'stream' from memory rather than a file
    using (var reader = new StreamReader(stream))
    using (var csv = new CsvReader(reader,CultureInfo.InvariantCulture))
    {
        csv.Configuration.Delimiter = "|"; // Set delimiter

        // Load csv to datatable and set dgv source
        using (var dr = new CsvDataReader(csv))
        {
            var dt = new DataTable();
            dt.Load(dr);
            dgvTst04_View.DataSource = dt; // EXECPTION IS THROWN HERE
        }
    }
}

然后在datagridview中得到以下结果:

Sample file test result

这可行!!

但是,当我尝试在具有5m以上记录的csv文件上实现相同的代码时,它运行一次就可以了(〜24s-大约就像我将其直接导入CsvHelper一样,没有其他预操作)。但是,当我尝试第二次运行它时,会引发System.OutOfMemoryException错误

对于上下文,我有64GB的内存,并且该过程似乎在2GB的使用量达到高峰(但不会下降)。所以我觉得“使用”没有正确处理内存/变量?如我所料,它在运行后会重新下降。以下诊断屏幕截图的前后:

在运行之前: Diagnostics before run

运行后: Diagnostics after run

我不是在代码中正确处理变量还是不处理它们?虽然我可以,但是如果我使用“使用”,则不必手动处理它们。

其他信息: 我在同一会话(10+)中多次在具有32k +数据行的文件上运行了相同的代码,具有相似的标头/数据行结构,平均运行时间为27毫秒,并且没有“ System.OutOfMemoryException”错误抛出。

让我知道您是否需要5m条记录示例文件(这是我在NZ政府网站上在线找到的示例文件,所以它是公共信息)。

谢谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...