3

嗨,有没有人有可行的示例代码来复制文件并支持在源已断开连接的情况下恢复它们?

在此示例中,我正在复制视频文件。如果源已断开,即 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);
  }
}
4

3 回答 3

3

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

于 2011-04-25T05:26:12.440 回答
1

创建一个与您复制的文件大小相同的文件。如果连接断开,请在文件中写入“书签”。文件末尾的一些任意字符串会告诉您从哪里停下来。

最好获取原始文件的哈希,以确定自上次复制尝试以来文件是否已更改。(如果文件不同,那么您应该检查目标中的数据与源中的数据,也许与数据的另一个散列。)

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

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

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

于 2011-04-25T05:33:27.877 回答
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 的文件。

于 2018-09-03T17:53:44.623 回答