C# - 复制文件并恢复支持

时间:2011-04-25 05:10:52

标签: c# stream copy filestream resume

您好 有没有人有可行的示例代码复制文件并支持恢复它们,如果源已被断开连接?

在这个例子中,我正在复制视频文件。如果源已断开连接,即USB已拔下,我怎样才能支持再次恢复它们?我在stackoverflow上尝试了一些代码,但在恢复后,视频文件似乎已损坏。 FileStream是视频传输/恢复的最佳解决方案吗?

欢迎任何其他指示或提示。

private void CreateNewCopyTo(FileStream source, FileStream dest) {
  int size = (source.CanSeek) ? Math.Min((int)(source.Length - source.Position), 0x2000) : 0x2000;
  byte[] buffer = new byte[size];
  int read;
  long fileLength = source.Length;
  while ((read = source.Read(buffer, 0, buffer.Length)) > 0) {
    dest.Write(buffer, 0, read);
    dest.Close();
    dest = new FileStream(dest.Name, FileMode.Append, FileAccess.Write);
  }
  dest.Close();
}

private void ResumeCopyTo(FileStream source, FileStream dest) {
  int size = (source.CanSeek) ? Math.Min((int)(source.Length - source.Position), 0x2000) : 0x2000;
  byte[] buffer = new byte[size];
  long TempPos = source.Position;
  while (true) {
    int read = source.Read(buffer, 0, buffer.Length);
    if (read <= 0)
      return;
    dest.Write(buffer, 0, read);
    dest.Close();
    dest = new FileStream(dest.Name, FileMode.Append, FileAccess.Write);
  }
}

3 个答案:

答案 0 :(得分:3)

尝试在ResumeCopyTo方法中插入source.Seek(dest.Length, SeekOrigin.Begin);作为第一行。

答案 1 :(得分:0)

创建一个与复制文件大小相同的文件。如果连接断开,请将“BookMark”写入文件。文件末尾的一些任意字符串告诉您中断的位置。

最好获取原始文件的哈希值,以确定自上次复制尝试后文件是否已更改。 (如果文件不同,那么您应该使用源中的数据检查目标中的数据,可能还有另一个数据哈希值。)

最重要的部分是在源和目的地中寻找两个文件中完全相同的点。在恢复尝试之前。

您需要确保搜索将为您提供源文件中的下一个字节。你离开的字节不一样。否则,您将获得具有单个重复字符的数据。哪会破坏数据。

(例如,如果源文件是12345678901234567890并且您的目的地是123456,您不希望在6恢复,您想在7恢复。否则您的目的地将是123456678901234567890)

答案 2 :(得分:0)

假设文件没有及时更改,我们可以使用您编写的功能。但是,应对其进行少量修改并将其简化为一个功能。

    private void ResumeCopy(FileStream source, FileStream dest)
    {
        byte[] buffer = new byte[0x10000]; //use 64kB buffer
        int read;

        source.Seek(dest.Length, SeekOrigin.Begin);

        while ((read = source.Read(buffer, 0, buffer.Length)) > 0)
        {
            dest.Write(buffer, 0, read);
            dest.Flush();
        }
    }

我们可以创建一个附加功能:

    private void ResumeCopyTo(string sourceFilePath, string destFilePath)
    {
        FileStream input = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read);
        FileStream output = new FileStream(destFilePath, FileMode.Append, FileAccess.Write);

        ResumeCopy(input, output);

        output.Close();
        input.Close();
    }

生产环境的想法:

  • 添加错误处理
  • 检查文件是否已更改(使用校验和)
  • 以独占模式打开源文件

顺便说一句: 这样,我通过质量很差的网络连接在9小时内复制了15 GB的文件。