Хеширование больших файлов в фоновом потоке - PullRequest
1 голос
/ 08 сентября 2011

У меня есть приложение Windows Forms, которое асинхронно хеширует файлы, используя BackgroundWorker.Я реализовал отмену, проверяя CancellationPending между каждым хэшируемым файлом.Само хеширование, по сути, таково:

var sha1 = new SHA1CryptoServiceProvider();
byte[] hash = sha1.ComputeHash(
    new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));

Единственная проблема с этим связана с особенно большими файлами - размером в сотни мегабайт или гигабайт - операция хеширования блокирует отмену до тех пор, пока она не будет завершена для этого файла.

Как лучше всего изменить это, чтобы можно было проверить отмену во время хэширования файла - например, каждые N миллисекунд или каждые N байтов?

Ответы [ 3 ]

2 голосов
/ 08 сентября 2011

Вы можете создать свой собственный отменяемый поток и предоставить его в качестве входных данных для функции хеширования. Что-то вроде этого:

class CancellableFileStream : FileStream {

  readonly BackgroundWorker backgroundWorker;

  public CancellableFileStream(BackgroundWorker backgroundWorker, String path, FileMode mode, FileAccess access, FileShare share)
    : base(path, mode, access, share) {
    this.backgroundWorker = backgroundWorker;
  }

  public override Int32 Read(Byte[] array, Int32 offset, Int32 count) {
    if (this.backgroundWorker.CancellationPending)
      return 0;
    return base.Read(array, offset, count);
  }

}
1 голос
/ 08 сентября 2011

SHA1 дружественный к чанку.Прочитайте файл по частям, используйте TransformBlock(), затем TransformFinalBlock(), когда файл заканчивается.

1 голос
/ 08 сентября 2011

Используйте TransformBlock и TransformFinalBlock вместо ComputeHash, перекачивая данные из вашего потока в алгоритм хеширования вручную - затем вставьте проверку отмены в ваш цикл.

...