c# CSV动态拆分

本文关键字:拆分 动态 CSV | 更新日期: 2023-09-27 18:12:50

我有多个1.5 GB的CSV文件,其中包含来自服务提供商的客户的多个帐户的计费信息。我正试图将大型CSV文件分割成较小的块,以处理和格式化其中的数据。

我不想推出我自己的CSV解析器,但这是我还没有看到的东西,所以请纠正我,如果我错了。1.5GB的文件中包含的信息顺序为:账户信息、账号、开票日期、交易、Ex gst、Inc gst、类型等行。

注意,这里的BillDate指的是开具发票的日期,所以有时在同一个CSV中会有两个以上的账单日期。

账单按:账号>账单日期>交易。

有的账户有10行交易明细,有的账户有30多万行交易明细。一个大的1.5GB的CSV文件包含大约800万行数据(我以前使用过UltraEdit)来剪切粘贴成更小的块,但这已经变得非常低效和耗时的过程。

我只是想在我的WinForm中加载大的CSV文件,点击一个按钮,它会将这个大文件分割成块,比如不大于25万行,但有些账单实际上大于25万行,在这种情况下,将它们放在一起,而不是将帐户分割成多个文件,因为它们是有序的。此外,我不希望在CSV中有多个账单日期的帐户,在这种情况下,拆分器可以创建另一个额外的拆分。

我已经有了一个WinForm应用程序,它可以在vsc# 2010中自动将CSV文件格式化为较小的文件。

实际上有可能处理这个非常大的CSV文件吗?我一直试图加载大文件,但MemoryOutOfException是一个烦恼,因为它每次崩溃,我不知道如何修复它。我愿意听取建议。

我认为我应该这样做:

  • 加载大CSV文件(但由于OutOfMemoryException而失败)。如何解决这个问题?
  • 按帐号名称、账单日期对数据进行分组,并统计每组的行数。
  • 然后创建一个整数数组
  • 将这个整数数组传递给文件分割器进程,该进程将获取这些数组并写入数据块。

如有任何建议,我将不胜感激。

谢谢。

c# CSV动态拆分

您可以使用CsvReader流式传输和解析数据,而无需一次将其全部加载到内存中。

是的关于……内存不足会发生在巨大的文件上。你需要认真对待你的处境。

像处理大多数问题一样,把所有事情分成几个步骤。

我以前也有过类似的情况(CSV格式的大数据文件,需要处理等)

我做了什么:

创建程序套件的第一步或其他什么东西,只是将您的大文件切割成许多小文件。我已经打破了5GB压缩PGP加密文件(解密后…(这是另一个令人头疼的问题)分成许多小块。您可以做一些简单的事情,如按顺序编号(即001,002,003…)

然后制作一个应用程序来执行INPUT处理。这里没有真正的业务逻辑。当涉及到业务逻辑时,我非常讨厌FILE IO,我喜欢数据放在SQL Server DB中的那种温暖而模糊的感觉。这就是我。我创建了一个线程池,有N个线程(比如5个,你决定你的机器可以处理多少)读取你创建的那些。csv部分文件。

每个线程读取一个文件。一对一的关系。因为它是文件I/O,所以确保不要同时运行太多的I/O。每个线程执行相同的基本操作。读取数据,将其放入db(表格式)的基本结构中,执行大量插入操作,然后结束线程。我使用LINQ to SQL,因为所有东西都是强类型的,但它们各自不同。db设计得越好,你以后做逻辑就越好。

在所有线程完成执行之后,数据库中就拥有了原始CSV中的所有数据。现在,您可以完成所有业务逻辑并从那里执行任何操作。这不是最好的解决方案,但考虑到我的情况/数据流/规模/需求,我不得不开发它。你可能会选择完全不同的东西。我想只是分享而已。

您可以使用外部排序。我认为您必须对文件进行初始遍历以确定适当的行边界,因为CSV记录可能不是固定长度的。

希望有一些现成的。net外部排序实现可以使用。

Microsoft.VisualBasic.FileIO命名空间中有一个非常有用的类,我用来处理CSV文件- TextFieldParser类。

它可能对大文件大小没有帮助,但它是内置的,可以处理带引号和不带引号的字段(即使混合在同一行中)。我在工作项目中用过几次。

不考虑程序集名称,如果你想知道,它可以与c#一起使用。