繁体   English   中英

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

[英]What is the best way to merge large files?

我必须合并数千个大文件(每个大约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);
    }
  }
}

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
}

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

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);
  }
}

假设您要为一个文件中要追加到另一个文件的每一行都必须为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>作为输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM