3

CA2202 警告 (CA2202 : Microsoft.Usage : オブジェクト 'compressedStream' は、メソッド 'Compression.InternalDecompress(byte[])' で複数回破棄できます。 System.ObjectDisposedException の生成を回避するには、呼び出す必要はありません次のコードから:

        using (var compressedStream = new MemoryStream(inputData))
        using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
        using (var resultStream = new MemoryStream())
        {
            zipStream.CopyTo(resultStream);
            return resultStream.ToArray();
        }

「using」ステートメントを削除して、try/finally パターンに置き換えようとしましたが、CA2000 が発生します (CA2000 : Microsoft.Reliability : In method 'Compression.InternalDecompress(byte[])', call System.IDisposable.Disposeオブジェクトへのすべての参照が範囲外になる前に、オブジェクト「ストリーム」で)。上記のコードを次のように置き換えてみました。

        MemoryStream decompressedData = null;
        MemoryStream stream = null;
        GZipStream decompressor = null;
        try
        {
            decompressedData = new MemoryStream();
            stream = new MemoryStream(inputData);
            decompressor = new GZipStream(stream, CompressionMode.Decompress, false);
            stream = null;

            int bytesRead = 1;
            int chunkSize = 4096;
            byte[] chunk = new byte[chunkSize];

            while ((bytesRead = decompressor.Read(chunk, 0, chunkSize)) > 0)
            {
                decompressedData.Write(chunk, 0, bytesRead);
            }

            decompressor = null;

            return decompressedData.ToArray();
        }
        finally
        {
            if (stream != null)
            {
                stream.Dispose();
            }

            if (decompressor != null)
            {
                decompressor.Dispose();
            }

            if (decompressedData != null)
            {
                decompressedData.Dispose();
            }
        }
4

3 に答える 3

1

This is what I ended up using - gets rid of both CA2000 and CA2202:

    private static MemoryStream GetMemoryStream()
    {
        return new MemoryStream();
    }

    private static byte[] InternalDecompress(byte[] inputData)
    {
        Debug.Assert(inputData != null, "inputData cannot be null");

        MemoryStream decompressedData = GetMemoryStream();
        MemoryStream inputDataMemoryStream = GetMemoryStream();

        GZipStream decompressor = null;

        try
        {
            inputDataMemoryStream.Write(inputData, 0, inputData.Length);
            inputDataMemoryStream.Position = 0;

            decompressor = new GZipStream(inputDataMemoryStream, CompressionMode.Decompress, false);

            int bytesRead;
            int chunkSize = 4096;
            byte[] chunk = new byte[chunkSize];

            while ((bytesRead = decompressor.Read(chunk, 0, chunkSize)) > 0)
            {
                decompressedData.Write(chunk, 0, bytesRead);
            }
        }
        finally
        {
            if (decompressor != null)
            {
                decompressor.Dispose();
            }
        }

        return decompressedData.ToArray();
    }
于 2012-02-21T13:02:28.583 に答える
1

これは私が使用するものです:

public class Compression
{
    public Compression()
    {

    }

    public byte[] Compress(byte[] buffer)
    {
        byte[] gzBuffer;

        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
            {
                zip.Write(buffer, 0, buffer.Length);
                zip.Close();
            }
            ms.Position = 0;

            MemoryStream outStream = new MemoryStream();

            byte[] compressed = new byte[ms.Length];
            ms.Read(compressed, 0, compressed.Length);

            gzBuffer = new byte[compressed.Length + 4];
            Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
            Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
        }

        return gzBuffer;
    }

    public byte[] Decompress(byte[] gzBuffer)
    {
        byte[] buffer;

        using (MemoryStream ms = new MemoryStream())
        {
            int msgLength = BitConverter.ToInt32(gzBuffer, 0);
            ms.Write(gzBuffer, 4, gzBuffer.Length - 4);

            buffer = new byte[msgLength];

            ms.Position = 0;
            using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
            {
                zip.Read(buffer, 0, buffer.Length);
            }
        }

        return buffer;
    }
}

または、プラグマステートメントをクラスに追加するだけです

#pragma warning disable 2202

namespace Your.Namespace
{
...
}

#pragma warning restore 2202
于 2012-02-20T17:31:12.367 に答える
0

これが私の試みです。動作し、CA2202 を回避します

    /// <summary>
    /// Compresses byte array to new byte array.
    /// </summary>
    public byte[] Compress(byte[] raw)
    {
        MemoryStream outStream = null;
        GZipStream tinyStream = null;
        byte[] retValue = null;
        try
        {
            outStream = new MemoryStream();
            tinyStream = new GZipStream(outStream, CompressionMode.Compress);
            using (var mStream = new MemoryStream(raw))
                mStream.CopyTo(tinyStream);
        }
        finally
        {
            if (tinyStream != null)
            {
                tinyStream.Dispose();
                retValue = outStream.ToArray();
            }
            else if (outStream != null)
            {
                retValue = outStream.ToArray();
                outStream.Dispose();
            }
        }
        return retValue;
    }
于 2016-04-15T16:06:26.807 に答える