我必须为巨大的有效负载计算哈希,所以我使用流而不是将所有请求内容加载到内存中。问题是这段代码之间有什么区别:
using (var md5 = MD5.Create())
using (var stream = await authenticatableRequest.request.Content.ReadAsStreamAsync())
{
return md5.ComputeHash(stream);
}
那一个:
using (var md5 = MD5.Create())
using (var stream = new MemoryStream())
{
await authenticatableRequest.request.Content.CopyToAsync(stream);
stream.Position = 0;
return md5.ComputeHash(stream);
}
我期望内部具有相同的行为,但也许我缺少一些东西。
答案 0 :(得分:4)
第一个版本看起来不错,让哈希器处理流读取。它是为此目的而设计的。
ComputeHash(stream)
将在while循环中读取块并重复调用TransformBlock()。
但是第二段代码 会将所有内容加载到内存中,所以不要这样做:
using (var stream = new MemoryStream())
{
await authenticatableRequest.request.Content.CopyToAsync(stream);
答案 1 :(得分:2)
我希望内部具有相同的行为
为什么?我的意思是,在一种情况下,您必须将所有内容都加载到内存中(因为您猜出了什么,所以您定义了一个内存流)。在另一种情况下则不一定。
答案 2 :(得分:2)
第二个代码段不仅将所有内容加载到内存中,而且将使用比HttpContent.ReadAsByteArrayAsync()
更多的内存。
MemoryStream是byte[]
buffer上的Stream API,其初始大小为零。随着数据写入其中,缓冲区必须reallocated到缓冲区中,大小是原始缓冲区的两倍。这可以创建临时缓冲区对象的 lot ,其大小超过最终内容。
通过向capacity
构造函数提供MemoryStream()
参数,从一开始就分配最大的预期缓冲区大小,可以避免这种情况。
充其量,这类似于致电:
var bytes = authenticatableRequest.request.Content.ReadAsByteArrayAsync();
return md5.ComputeHash(bytes);