【问题标题】:How to create copy of file using StreamReader and StreamWriter如何使用 StreamReader 和 StreamWriter 创建文件副本
【发布时间】:2015-10-27 14:26:36
【问题描述】:

我需要使用 StreamReader 在控制台应用程序上读取 .txt 文件,然后创建一个名称不同但内容相同的新文件或备份。问题是我不知道如何使用第一个文件中的内容放入新文件中。 (这是学校的事情,我是 C# 新手)

using System;
using System.IO;
namespace UserListCopier
{
    class Program
    {
        static void Main()
        {
            string fineName = "zombieList.txt";

            StreamReader reader = new StreamReader(fineName);

            int lineNumber = 0;

            string line = reader.ReadLine();

            while (line != null) {
                lineNumber++;
                Console.WriteLine("Line {0}: {1}", lineNumber, line);
                line = reader.ReadLine();
            }

            StreamWriter writetext = new StreamWriter("zombieListBackup.txt");

            writetext.Close();
            System.Console.Read();
            reader.Close();
        }
    }
}

【问题讨论】:

标签: c# copy streamreader streamwriter


【解决方案1】:
public static void ReadFromFile()
{
    using (StreamReader sr = File.OpenText(@"D:\new.txt"))
    {
        string line = null;
        while ((line = sr.ReadLine()) != null)
        {
            using (StreamWriter sw = File.AppendText(@"D:\output.txt"))
            {
                sw.WriteLine(line);
            }
        }
    }
}

【讨论】:

  • 您正在为每一行创建新的作家。这是一种非常低效的方式。
【解决方案2】:

回答实际问题:

using var reader = new StreamReader(someInput);
using var writer = new StreamWriter(someOutput);
reader.CopyTo(writer.BaseStream);

【讨论】:

  • StreamReader 没有 CopyTo 方法。 BaseStream 属性应该在这里调用reader.BaseStream.CopyTo()
【解决方案3】:

对于磁盘上的文件,您只需要File.Copy(inputPath, outputPath)。我不确定这是否有效地流式传输内容,或者是否将其全部读入内存然后一次性全部写入。

因此,对于大文件,或者如果您的流无法解析为磁盘上的路径,您可以使用以下函数高效地从一个文件复制到另一个文件:

private void copyFile(string inputPath, string outputPath)
{
    using (var inputStream = StreamReader(inputPath))
    {
        using (var outputStream = StreamWriter(outputPath))
        {
            copyToOutputStream(inputStream, outputStream);
        }
    }
}

private void copyToOutputStream(StreamReader inputStream, StreamWriter outputStream)
{
    string line = null;
    while ((line = inputStream.ReadLine()) != null)
    {
        outputStream.WriteLine(line);
    }
    outputStream.Write(inputStream.ReadToEnd());
}

此函数一次一行地从输入流复制到输出流,直到输入流结束。这意味着它一次在内存中只有一行(而不是整个文件),并且它可以在第一个流完成读入/生成之前开始写入磁盘。

【讨论】:

  • 请注意,这将导致二进制数据出现问题 - 或者通常是任何不包含换行符且非常大的文件。它还可以更改换行符的类型(LF -> CRLF)。
【解决方案4】:

假设您已经打开了两个流,类似于@jeff 的解决方案,但是您可以缓冲传输而不是 ReadToEnd(不是真正有效的蒸汽)。

_bufferSize 是一个 int,将其设置为适合您的缓冲区大小(1024、4096 等)

private void CopyStream(Stream src, Stream dest)
{
    var buffer = new byte[_bufferSize];
    int len;
    while ((len = src.Read(buffer, 0, buffer.Length)) > 0)
    {
        dest.Write(buffer, 0, len);
    }
}

这是一个要点,包含一个计算传输速度的类 https://gist.github.com/dbones/9298655#file-streamcopy-cs-L36

【讨论】:

  • 我认为这应该是正确的答案,因为它节省内存
【解决方案5】:

这样就可以了:

using System;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var reader = new StreamReader(@"C:\MyOriginalFile.txt"))
            using (var writer = new StreamWriter(@"C:\MyNewFile.txt", append: false))
            {
                writer.Write(reader.ReadToEnd());
            }
            Console.Read();
        }
    }
}

【讨论】:

  • 但这不会一口气读完整个输入流,然后一口气写出来吗?这不会失去使用流的意义吗?如果数据很大(数 GB),那么您将一次性将整个数据存储在内存中,而不仅仅是一个滑动窗口。
猜你喜欢
  • 2012-02-22
  • 1970-01-01
  • 2013-12-17
  • 2019-02-26
  • 1970-01-01
  • 2013-05-15
  • 2013-01-05
  • 1970-01-01
  • 2017-01-21
相关资源
最近更新 更多