如何读取多个文本文件并将其保存到一个文本文件中?

时间:2009-05-19 20:36:37

标签: c# text file

在我的情况下,我有五个巨大的文本文件,我必须将其嵌入到一个文本文件中。

我尝试使用StreamReader(),但我不知道如何让它再读一个文件,我是否必须分配另一个变量?

展示一个例子将非常感激。

2 个答案:

答案 0 :(得分:8)

新答案

(见下面的原始答案的解释。)

static void CopyFiles(string dest, params string[] sources)
{
    using (TextWriter writer = File.CreateText(dest))
    {
        // Somewhat arbitrary limit, but it won't go on the large object heap
        char[] buffer = new char[16 * 1024]; 
        foreach (string source in sources)
        {
            using (TextReader reader = File.OpenText(source))
            {
                int charsRead;
                while ((charsRead = reader.Read(buffer, 0, buffer.Length)) > 0)
                {
                    writer.Write(buffer, 0, charsRead);
                }
            }
        }
    }
}

这个新答案很像Martin的方法,除了:

  • 读入较小的缓冲区; 16K几乎在所有情况下都是可以接受的,并且不会最终出现在大对象堆上(不会被压缩)
  • 它读取 text 数据而不是二进制数据,原因有两个:
    • 可以轻松修改代码以将编码转换为另一种编码
    • 如果每个输入文件包含一个字节顺序标记,读取器将跳过该标记,而不是以输入文件边界处输出文件中散布的字节顺序标记结束

原始回答

Martin Stettner在下面的答案中指出了一个问题 - 如果第一个文件没有换行结束,它仍会在输出文件中创建换行符。此外,它会将换行符转换为“\ r \ n”,即使它们之前只是“\ r”或“\ n”。最后,对于长线使用大量数据存在毫无意义的风险。

类似的东西:

static void CopyFiles(string dest, params string[] sources)
{
    using (TextWriter writer = File.CreateText(dest))
    {
        foreach (string source in sources)
        {
            using (TextReader reader = File.OpenText(source))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    writer.WriteLine(line);
                }
            }
        }
    }
}

请注意,这会逐行读取,以避免一次读取太多内存。如果您乐意将每个文件完全读入内存(仍然是一次一个),您可以更简单:

static void CopyFiles(string dest, params string[] sources)
{
    using (TextWriter writer = File.CreateText(dest))
    {
        foreach (string source in sources)
        {
            string text = File.ReadAllText(source);
            writer.Write(text);
        }
    }
}

答案 1 :(得分:2)

修改

正如Jon Skeet指出的那样,文本文件通常应该以不同于二进制文件的方式处理 。

我只是留下这个答案,因为如果您有非常大的文件并且没有通过编码问题(例如输出文件中具有不同编码或多个Byte Order Marks的不同输入文件),则可能会更高效:

public void CopyFiles(string destPath, string[] sourcePaths) {
  byte[] buffer = new byte[10 * 1024 * 1024]; // Just allocate a buffer as big as you can afford
  using (var destStream= = new FileStream(destPath, FileMode.Create) {
    foreach (var sourcePath in sourcePaths) {
      int read;
      using (var sourceStream = FileStream.Create(sourcePath, FileMode.Open) {
        while ((read = sourceStream.Read(buffer, 0, 10*1024*1024)) != 0)
          destStream.Write(buffer, 0, read);
      }
    }
  }
}