在后台线程上散列大文件

本文关键字:文件 后台 线程 | 更新日期: 2023-09-27 18:07:50

我有一个Windows窗体应用程序,它使用BackgroundWorker异步散列文件。我通过检查每个散列文件之间的CancellationPending来实现取消。哈希本身本质上是这样的:

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

唯一的问题是,对于特别大的文件——数百兆或千兆字节的大小——哈希操作会阻止取消,直到该文件完成。

最好的修改方法是什么,以便在文件被散列时检查取消-例如每N毫秒或每N字节?

在后台线程上散列大文件

您可以创建自己的可取消流,并将其作为哈希函数的输入。下面的内容:

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

使用TransformBlock和TransformFinalBlock代替ComputeHash,从你的流中手动抽取数据到哈希算法-然后在循环中插入一个取消检查

SHA1是块友好的。按块读取文件,使用TransformBlock(),然后在文件结束时使用TransformFinalBlock()