.net 在计算Azure Blob的MD5和SHA256时重用流

d7v8vwbk  于 2023-06-25  发布在  .NET
关注(0)|答案(1)|浏览(127)

我必须使用Azure函数计算存储在Azure Blob存储帐户中的文件的MD5和SHA256。我尝试使用DownloadContent方法将文件下载到内存中,但是对于大文件(超过4GB),我的内存不足(我不得不扩大规模,这是昂贵的)。我发现了另一个方法DownloadStreaming,它可以很好地进行第一次计算(几乎没有额外的内存使用),但在计算第二次哈希之前,我必须再次下载文件,因为流是空的。我尝试在该流上调用Position = 0,但我得到的异常类型不受支持。有没有办法使用DownloadStreaming而不重新下载文件?
下面是我使用的代码:

var sourceFile = await blobClient.DownloadStreamingAsync();
byte[] md5Result;
byte[] sha256Result;

using (var md5 = MD5.Create())
{
   md5Result = md5.ComputeHash(sourceFile.Value.Content);
}

sourceFile = await blobClient.DownloadStreamingAsync();
using (var sha256 = SHA256.Create())
{
   sha256Result = sha256.ComputeHash(sourceFile.Value.Content);
}
gfttwv5a

gfttwv5a1#

您可以循环读取流,并手动使用md5.TransformBlocksha256.TransformBlock逐位计算哈希值。

  • 你不需要传递一个outputBuffer给这个函数,你可以传递null
  • 在检索哈希之前,您需要调用TransformFinalBlock
  • 考虑在异步函数上使用CancellationToken
var inputBuffer = new byte[4000];
using var sourceFile = await blobClient.DownloadStreamingAsync();
using var md5 = MD5.Create();
using var sha256 = SHA256.Create();

int bytesRead;
while ((bytesRead = await sourceFile.ReadAsync(inputBuffer.AsMemory())) > 0)
{
    md5.TransformBlock(inputBuffer, 0, bytesRead, null, 0);
    sha256.TransformBlock(inputBuffer, 0, bytesRead, null, 0);
}
md5.TransformFinalBlock(inputBuffer, 0, 0);  // finish hash calculation
var md5Result = md5.Hash;

sha256.TransformFinalBlock(inputBuffer, 0, 0);  // finish hash calculation
var sha256Result = sha256.Hash;

相关问题