【问题标题】:Copying files using C# [duplicate]使用 C# 复制文件 [重复]
【发布时间】:2025-12-06 15:20:06
【问题描述】:

可能重复:
Best way to copy between two Stream instances - C#

我知道我可以使用 File.Copy,但我更感兴趣的是做更长的时间,只是为了教育目的。

现在,我要讨论的方法是使用 StreamReader 和 StreamWriter(或 FileStreams)。

在我看来,我会将文件(作为二进制文件)读入内存,然后将文件写入新位置。这让我觉得可能会出现错误,因为
1) 整个文件正在加载到内存中(我不知道文件有多大)和
2)与复制一个字节,粘贴一个字节(我认为这是流式传输的工作方式)相比,这将是耗时的,因为我们必须等待整个文件存储在内存中,然后才能开始粘贴。

那么,有很长的路要问,我将如何流式传输复制和粘贴作业?

【问题讨论】:

  • 这很简单:读取一个块,写入一个块直到 EOF。但是您尝试过什么?
  • @raman 我已经尝试了一些事情并最终陷入了一个循环 - 然后我开始在线查找,其他所有答案都暗示了一条不同的路线。不同路线的问题是我不知道路线是否好,因此最好在这个网站上询问其他人可以评论这些建议
  • @CodeCaster - 实际上,我们在我正在处理的一个项目中有类似的东西,但我再次遇到的问题是不知道它是否好,主要是因为我在工作中被困住了.NET 2.0 - 它使我的学习变得困难,因为我被旧技术所包围 - 我不想在 OP 中逐块提及读/写,因为它“引导答案”太多了 - 相反,看答案,大多数同意你的观点,但我也有一个异步。选项并学到了很多关于 File.Copy 的知识

标签: c# filestream


【解决方案1】:

那么,有很长的路要问,我将如何流式传输复制和粘贴作业?

不是将每个字节单独读取到内存中,也不是将整个 文件 读取到内存中,而是介于两者之间 - 创建一个缓冲区,例如32K,并要求输入流读取那么多数据。写出你读过的字节数,然后重复直到没有更多的数据要读。所以像:

public void Copy(Stream input, Stream output)
{
    byte[] buffer = new byte[32 * 1024];
    int bytesRead;
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
    {
        output.Write(buffer, 0, bytesRead);
    }
}

这并不像 可能那样有效,因为您不是同时阅读和写作。异步 IO 可以解决这个问题,但会使它更加复杂 - 而且操作系统完全有可能足够聪明,可以在你写作时继续阅读......

请注意,除非您实际阅读文本,否则您肯定希望使用 Stream 而不是 TextReader / TextWriter

【讨论】:

  • 完美,正是我希望的答案类型(你的书今天从亚马逊送来:))
  • “正是我希望的答案类型” - 然后将您的想法纳入您的下一个问题。我们猜不出你已经想到了什么。 ;-)
  • @DaveRook:查看示例代码的编辑 - 具有讽刺意味的是,这与您在书中某处找到的几乎相同 :)
【解决方案2】:

您可以以 1 MB 的块为单位读取/写入文件(例如)。 MSDN has an example 展示了如何做到这一点。

【讨论】:

    【解决方案3】:
    1. 创建一个空的目标文件
    2. 从源文件中读取一个缓冲区(比如说 1024 字节)
    3. 将缓冲区写入目标文件
    4. 重复 2 直到一切完成

    【讨论】: