我有一个非常基本的问题。我有几个文本文件,每个文件的大小都是几GB。我有一个C#WPF应用程序,我用它来处理类似的数据文件,但没有接近那个大小(现在可能大约200-300mb)。我怎样才能有效地读取这些数据,然后在处理之后将其写入其他地方,而不会冻结和崩溃?从根本上说,从一个非常大的文件读取的最佳方式是什么?对于我现在的低规模应用程序,我使用System.IO.File.ReadAllLines
来阅读并使用streamwriter
来编写。我确定这两种方法不适合这种大文件。我对C#没有多少经验,任何帮助都将不胜感激!
答案 0 :(得分:3)
如果你可以逐行完成这个,那么答案很简单:
如果你想让它更快一些,那么将它们放在三个BlockingCollections
中,指定的上限为10,这样一个较慢的步骤永远不会等待更快的步骤。如果您可以输出到不同的物理光盘(如果输出到光盘)。
OP甚至在被询问该过程是否是逐行(两次)之后改变了规则。
答案 1 :(得分:1)
这可能是某种重叠的转换。
https://msdn.microsoft.com/en-us/library/dd997372(v=vs.110).aspx
首先,您希望将目标文件分配到与估计值接近的结果大小。在大多数情况下,过冲可能比下冲更可取,您可以始终截断到给定长度,但增长可能需要非连续分配。如果预计会出现过度增长,您可以将文件分配为"稀疏"文件。
选择大于或等于512字节的任意(可能是二进制功率)块大小(测试以找到最佳性能)。
映射源文件的2个块。这是你的源缓冲区。
映射目标文件的2个块。这是您的目标缓冲区。
在一个区块内的线上操作。从源块读取,写入目标块。
转换块边界后,执行"缓冲交换"交换上一个已完成的块以进行下一个块。
有几种方法可以完成这些任务。
如果您愿意,您可以一次分配更多的块用于操作,但您需要应用"三重缓冲"利用重叠操作的策略。如果写入比读取慢得多,您甚至可以使用与三重缓冲相同的模式实现无界内存缓冲。
根据您的数据,您也可以将块分发到不同的线程,即使它是基于线路的"文件。
如果每一行都依赖于以前的数据,则可能无法加速操作。如果没有,在执行操作之前索引文件中的行将允许多个工作线程,每个线程在独立块上运行。
如果我需要详细说明任何事情,请说明哪一部分。