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

コピーするファイルと同じサイズのファイルを作成します。また、接続が切断されている場合は、ファイルに「ブックマーク」を書き込みます。ファイルの最後にある任意の文字列で、中断した場所を示します。

元のファイルのハッシュを取得して、最後のコピー試行以降にファイルが変更されたかどうかを判断するのが最適です。(ファイルが異なる場合は、宛先のデータとソースのデータ、おそらくデータの別のハッシュを確認する必要があります。)

最も重要な部分は、両方のファイルのまったく同じポイントへのソースと宛先を探すことです。再開を試みる前。

シークによってソースファイルの次のバイトが確実に提供されるようにする必要があります。中断したのと同じバイトではありません。そうしないと、データに重複する文字が1つ残ってしまいます。これはデータを破壊します。

(たとえば、ソースファイルが12345678901234567890で、宛先が123456になっている場合、6で再開したくない、7で再開したい、そうでない場合、宛先は123456678901234567890になります)

于 2011-04-25T05:33:27.877 に答える
0

ファイルが時間の経過とともに変化しないと仮定すると、作成した関数を使用できます。ただし、これらを少し変更して1つの関数に簡略化する必要があります。

    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時間で15GBのファイルをコピーしました。

于 2018-09-03T17:53:44.623 に答える