为了账号安全,请及时绑定邮箱和手机立即绑定

CopyToAsync 与 ReadAsStreamAsync 的巨大请求负载

CopyToAsync 与 ReadAsStreamAsync 的巨大请求负载

C#
ITMISS 2021-11-07 20:01:10
我必须为巨大的有效负载计算哈希,所以我使用流而不是将所有请求内容加载到内存中。问题是这段代码之间有什么区别: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);}我希望在内部有相同的行为,但也许我错过了一些东西。
查看完整描述

3 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

第一个版本看起来不错,让哈希器处理流读取。它是为此而设计的。


ComputeHash(stream) 将在 while 循环中读取块并重复调用 TransformBlock()。


但是第二段代码会将所有内容加载到内存中,所以不要这样做:


using (var stream = new MemoryStream())

{

    await authenticatableRequest.request.Content.CopyToAsync(stream);


查看完整回答
反对 回复 2021-11-07
?
杨魅力

TA贡献1811条经验 获得超6个赞

第二个片段,不仅一切都加载到内存中,它将使用更比内存HttpContent.ReadAsByteArrayAsync()。


MemoryStream 是byte[]缓冲区上的Stream API,缓冲区的初始大小为零。随着数据写入其中,缓冲区必须重新分配到两倍于原始缓冲区的缓冲区中。这会创建很多大小超过最终内容的临时缓冲区对象。


这可以通过向构造函数提供capacity参数从一开始就分配最大的预期缓冲区大小来避免MemoryStream()。


充其量,这将类似于调用:


var bytes = authenticatableRequest.request.Content.ReadAsByteArrayAsync();

return md5.ComputeHash(bytes);


查看完整回答
反对 回复 2021-11-07
?
拉莫斯之舞

TA贡献1820条经验 获得超10个赞

我希望在内部也有同样的行为,

为什么?我的意思是,在一种情况下,您必须将所有内容加载到内存中(因为猜猜是什么,您定义了一个内存流)。在其他情况下不一定。


查看完整回答
反对 回复 2021-11-07
  • 3 回答
  • 0 关注
  • 419 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信