满足 MemoryStream 和 CryptoStream 的代码分析处置规则

本文关键字:规则 代码 MemoryStream CryptoStream 满足 | 更新日期: 2023-09-27 18:34:22

我在满足用于释放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()的调用会导致后一种警告。

有没有办法同时满足这两个条件?我认为问题是可能会关闭它的异常路径,但我对这些类的工作原理不是很熟悉。

满足 MemoryStream 和 CryptoStream 的代码分析处置规则

您可以使用

var bytes = transform.TransformFinalBlock(buffer, 0, buffer.Length);

如果没有流,则无需担心处理它们;)

如果它触发,我个人倾向于在我的源代码中抑制该规则,因为大多数对象在两次释放时都没有问题。 但是,如果您想在不抑制的情况下满足规则,则需要执行以下操作:

        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;

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