C # - Копирование файлов и возобновление поддержки - PullRequest
3 голосов
/ 25 апреля 2011

Привет. Есть ли у кого-нибудь работающий пример кода, который копирует файлы и поддерживает их возобновление, если источник отключен?

В этом примере я копирую видеофайлы.Если источник отключен, т. Е. 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 ]

3 голосов
/ 25 апреля 2011

Попробуйте вставить source.Seek(dest.Length, SeekOrigin.Begin); в качестве первой строки в методе ResumeCopyTo.

0 голосов
/ 03 сентября 2018

Предполагая, что файл не изменяется во времени, мы можем использовать функции, которые вы написали. Однако их следует немного изменить и упростить до одной функции.

    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();
    }

Идеи для производственной среды:

  • добавить обработку ошибок
  • проверить, не изменился ли файл (используйте контрольную сумму)
  • открыл исходный файл в монопольном режиме

КСТАТИ: Таким образом, я скопировал файл размером 15 ГБ за 9 часов через сетевое соединение очень низкого качества.

0 голосов
/ 25 апреля 2011

создайте файл того же размера, что и файл, который вы копируете.И если соединение разорвано, напишите «BookMark» в файл.Некоторая произвольная строка в конце файла, которая сообщает вам, где вы остановились.

Лучше всего получить хеш исходного файла, чтобы определить, изменился ли файл со времени последней попытки копирования.(если файл отличается, то вы должны проверить данные в месте назначения с данными в источнике, возможно, с другим хешем данных.)

Самая важная часть, которую нужно искать в источнике иназначение в одну и ту же точку в обоих файлах.до попытки возобновления.

Вы хотите убедиться, что ваш запрос даст вам следующий байт в исходном файле.Не тот байт, на котором вы остановились.В противном случае у вас останутся данные с одним повторяющимся символом.Что повредит данные.

(например, если исходный файл 12345678901234567890 и ваш пункт назначения достиг 123456, вы не хотите возобновлять на 6, вы хотите возобновить на 7. в противном случае ваш пункт назначения будет 123456678901234567890)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...