在C#中读取非常大的文本文件的最快方法

时间:2015-06-16 17:00:50

标签: c# wpf large-files

我有一个非常基本的问题。我有几个文本文件,每个文件的大小都是几GB。我有一个C#WPF应用程序,我用它来处理类似的数据文件,但没有接近那个大小(现在可能大约200-300mb)。我怎样才能有效地读取这些数据,然后在处理之后将其写入其他地方,而不会冻结和崩溃?从根本上说,从一个非常大的文件读取的最佳方式是什么?对于我现在的低规模应用程序,我使用System.IO.File.ReadAllLines来阅读并使用streamwriter来编写。我确定这两种方法不适合这种大文件。我对C#没有多少经验,任何帮助都将不胜感激!

2 个答案:

答案 0 :(得分:3)

如果你可以逐行完成这个,那么答案很简单:

  1. 阅读一行。
  2. 处理这条线。
  3. 写下这一行。
  4. 如果你想让它更快一些,那么将它们放在三个BlockingCollections中,指定的上限为10,这样一个较慢的步骤永远不会等待更快的步骤。如果您可以输出到不同的物理光盘(如果输出到光盘)。

    OP甚至在被询问该过程是否是逐行(两次)之后改变了规则。

    1. 读取行以生成工作单元(打开以关闭标签)。
    2. 处理工作单元。
    3. 编写工作单元。

答案 1 :(得分:1)

这可能是某种重叠的转换。

https://msdn.microsoft.com/en-us/library/dd997372(v=vs.110).aspx

首先,您希望将目标文件分配到与估计值接近的结果大小。在大多数情况下,过冲可能比下冲更可取,您可以始终截断到给定长度,但增长可能需要非连续分配。如果预计会出现过度增长,您可以将文件分配为"稀疏"文件。

选择大于或等于512字节的任意(可能是二进制功率)块大小(测试以找到最佳性能)。

映射源文件的2个块。这是你的源缓冲区。

映射目标文件的2个块。这是您的目标缓冲区。

在一个区块内的线上操作。从源块读取,写入目标块。

转换块边界后,执行"缓冲交换"交换上一个已完成的块以进行下一个块。

有几种方法可以完成这些任务。

如果您愿意,您可以一次分配更多的块用于操作,但您需要应用"三重缓冲"利用重叠操作的策略。如果写入比读取慢得多,您甚至可以使用与三重缓冲相同的模式实现无界内存缓冲。

根据您的数据,您也可以将块分发到不同的线程,即使它是基于线路的"文件。

如果每一行都依赖于以前的数据,则可能无法加速操作。如果没有,在执行操作之前索引文件中的行将允许多个工作线程,每个线程在独立块上运行。

如果我需要详细说明任何事情,请说明哪一部分。