读取多个非常大的文件的最佳方法

jmm*_*487 3 c# performance file-io file text-files

我需要帮助找出最快的方法来读取每个文件中超过500,000行的大约80个文件,并写入一个主文件,每个输入文件的行作为主列中的列.必须将主文件写入文本编辑器(如记事本)而不是Microsoft产品,因为它们无法处理行数.

例如,主文件应如下所示:

File1_Row1,File2_Row1,File3_Row1,...

File1_Row2,File2_Row2,File3_Row2,...

File1_Row3,File2_Row3,File3_Row3,...
Run Code Online (Sandbox Code Playgroud)

等等

到目前为止,我尝试了2个解决方案:

  1. 创建一个锯齿状数组以将每个文件的内容保存到一个数组中,然后一旦读取所有文件中的所有行,就编写主文件.此解决方案的问题是Windows操作系统内存引发错误,即使用了太多的虚拟内存.
  2. 为读取特定行号的80个文件中的每个文件动态创建一个阅读器线程,一旦所有线程读完一行,将这些值组合并写入文件,并对所有文件中的每一行重复.这个解决方案的问题是它非常慢.

有没有人能够以更快的方式阅读这么多大文件?

Mik*_*ray 5

最好的方法是打开输入文件,StreamReader每个输入文件为a 和StreamWriter输出文件.然后循环浏览每个阅读器并读取一行并将其写入主文件.这样你一次只能加载一行,所以应该有最小的内存压力.我能够在37秒内复制80~500,000行文件.一个例子:

using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;

class MainClass
{
    static string[] fileNames = Enumerable.Range(1, 80).Select(i => string.Format("file{0}.txt", i)).ToArray();

    public static void Main(string[] args)
    {
        var stopwatch = Stopwatch.StartNew();
        List<StreamReader> readers = fileNames.Select(f => new StreamReader(f)).ToList();

        try
        {
            using (StreamWriter writer = new StreamWriter("master.txt"))
            {
                string line = null;
                do
                {
                    for(int i = 0; i < readers.Count; i++)
                    {
                        if ((line = readers[i].ReadLine()) != null)
                        {
                            writer.Write(line);
                        }
                        if (i < readers.Count - 1)
                            writer.Write(",");
                    }
                    writer.WriteLine();
                } while (line != null);
            }
        }
        finally
        {
            foreach(var reader in readers)
            {
                reader.Close();
            }
        }
        Console.WriteLine("Elapsed {0} ms", stopwatch.ElapsedMilliseconds);
    }
}
Run Code Online (Sandbox Code Playgroud)

我假设所有输入文件具有相同的行数,但是当至少一个文件为您提供数据时,您应该添加逻辑以保持读取.