使用 MemoryStream 和 CryptoStream 满足代码分析处置规则 [重复]
Posted
技术标签:
【中文标题】使用 MemoryStream 和 CryptoStream 满足代码分析处置规则 [重复]【英文标题】:Satisfying Code Analysing disposal rule with MemoryStream and CryptoStream [duplicate] 【发布时间】:2014-12-16 20:58:37 【问题描述】:我在满足用于处置 MemoryStream
对象的代码分析规则时遇到问题。
这是我现在的代码:
byte[] bytes;
MemoryStream stream = new MemoryStream();
using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
cs.Write(buffer, 0, buffer.Length);
bytes = stream.ToArray();
stream.Close();
return bytes;
这会导致警告说流可能被释放两次,或者可能不被释放(每个警告一个)。
我也尝试将其包装到 using(MemoryStream stream = new MemoryStream())
块中。这会导致前一个警告。
最后,删除对Close()
或Dispose()
的调用会导致后一个警告。
有没有办法同时满足这两个条件?我认为问题是可能会关闭它的异常路径,但我对这些类的工作方式不是很熟悉。
【问题讨论】:
【参考方案1】:你可以通过使用丢弃所有的流
var bytes = transform.TransformFinalBlock(buffer, 0, buffer.Length);
如果没有流,则无需担心处理它们;)
【讨论】:
手头问题的真正解决方案(问题本身也是完全相同的样本***.com/questions/3831676/…的副本)【参考方案2】:如果它触发,我个人倾向于在我的源代码中禁止该规则,因为大多数对象都没有被处理两次的问题。但是,如果您想在不压制的情况下满足规则,则需要这样做:
byte[] bytes = new byte[1024];
byte[] buffer = new byte[1024];
ICryptoTransform transform = null;
MemoryStream stream = null;
try
stream = new MemoryStream();
MemoryStream tempStream = stream
using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
// set stream to null immediately so it doesn't get disposed by finally
stream = null;
cs.Write(buffer, 0, buffer.Length);
bytes = tempStream.ToArray();
finally
if (stream != null)
stream.Dispose();
return bytes;
【讨论】:
您的代码导致 CA2202 不要多次处理对象.. 不错不错。我将 steam = null 语句移到 using 语句中的第一行代码,FXCop 很高兴。我仍然不喜欢这条规则。 没有警告,但是你现在在设置stream = null
后访问stream.ToArray()
!
当CryptoStream
被释放时(当using
块结束时),它在MemoryStream
上调用Close
,后者又调用Dispose
。
因此,您无需亲自致电Dispose
(通过using
)或Close
。这样,stream
只会被处理一次。
MemoryStream stream = new MemoryStream();
using (CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
cs.Write(buffer, 0, buffer.Length);
return stream.ToArray();
【讨论】:
如果 CryptoStream 构造函数抛出,该代码可能会使 MemoryStream 未处理。 没错,但这并不是(IMO)大问题。一个空的 MemoryStream 不大,最终还是会被 GC 处理。希望 CryptoStream 的 ctor 不太可能抛出。如果不触发代码分析警告之一,我看不到解决方法。 我倾向于禁止这条规则并使用 2 using 语句。但是,如果您不想压制并始终处置,我会使用 try/finally 块更新我的答案以满足规则。 @BlorgbeardMemoryStream
设计为无操作 Dispose
,因为它必须保持内部缓冲区(托管字节数组)处于活动状态以供以后调用 ToArray
。所以即使不处理“巨大的MemoryStream
”也不是问题(很高兴有正确的代码,但没有真正的区别)。以上是关于使用 MemoryStream 和 CryptoStream 满足代码分析处置规则 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用 OpenXML 和 MemoryStream 在 ASP.NET 程序中编辑和保存 .docx
PCM Wave 文件中的数据长度使用 MemoryStream 和 WaveFileWriter
使用 NAudio 读取包含作品音频的 MemoryStream