合并大文件的最佳方法是什么?

时间:2015-10-28 12:05:50

标签: c# .net io

我必须合并数千个大文件(每个大约200MB)。我想知道合并这些文件的最佳方法是什么。行将有条件地复制到合并文件。可以使用File.AppendAllLines或使用Stream.CopyTo吗?

使用File.AppendAllLines

for (int i = 0; i < countryFiles.Length; i++){
   string srcFileName = countryFiles[i];
   string[] countryExtractLines = File.ReadAllLines(srcFileName);  
   File.AppendAllLines(actualMergedFileName, countryExtractLines);
}

使用Stream.CopyTo

using (Stream destStream = File.OpenWrite(actualMergedFileName)){
  foreach (string srcFileName in countryFiles){
    using (Stream srcStream = File.OpenRead(srcFileName)){
        srcStream.CopyTo(destStream);
    }
  }
}

3 个答案:

答案 0 :(得分:3)

sab669的答案是正确的,你想使用StreamReader然后循环遍历文件的每一行...... 我建议单独编写每个文件,否则你将很快用尽许多200mb文件

例如:

foreach(File f in files)
{
    List<String> lines = new List<String>();
    string line;
    int cnt = 0;
    using(StreamReader reader = new StreamReader(f)) {
        while((line = reader.ReadLine()) != null) {
            // TODO : Put your conditions in here
            lines.Add(line);
            cnt++;
        }
    }
    f.Close();
    // TODO : Append your lines here using StreamWriter
}

答案 1 :(得分:3)

您可以一个接一个地编写文件。例如:

static void MergingFiles(string outputFile, params string[] inputTxtDocs)
{
    using (Stream outputStream = File.OpenWrite(outputFile))
    {
      foreach (string inputFile in inputTxtDocs)
      {
        using (Stream inputStream = File.OpenRead(inputFile))
        {
          inputStream.CopyTo(outputStream);
        }
      }
    }
}

在我看来,上面的代码实际上是高性能的,因为Stream.CopyTo()具有非常简单的算法,因此该方法非常有效。反射器使其核心如下:

private void InternalCopyTo(Stream destination, int bufferSize)
{
  int num;
  byte[] buffer = new byte[bufferSize];
  while ((num = this.Read(buffer, 0, buffer.Length)) != 0)
  {
     destination.Write(buffer, 0, num);
  }
}

答案 2 :(得分:2)

假设您有一个条件必须为true(即谓词),以便将一个文件中的每一行添加到另一个文件中。

您可以按如下方式有效地处理:

var filteredLines = 
    File.ReadLines("MySourceFileName")
    .Where(line => line.Contains("Target")); // Put your own condition here.

File.AppendAllLines("MyDestinationFileName", filteredLines);

此方法可扩展到多个文件,并避免将整个文件加载到内存中。

如果不是将所有行追加到文件中,而是想要替换内容,那么你可以这样做:

File.WriteAllLines("MyDestinationFileName", filteredLines);

而不是

File.AppendAllLines("MyDestinationFileName", filteredLines);

另请注意,如果您不使用UTF8,这些方法的重载允许您指定编码。

最后,不要被不一致的方法命名抛出。File.ReadLines()不会将所有行读入内存,但File.ReadAllLines()会这样做。但是,File.WriteAllLines()不会将所有行缓冲到内存中,或者期望它们全部缓冲在内存中;它使用IEnumerable<string>作为输入。