Question

I am trying to utilize the INFLATE compression stream in .NET using a DeflateStream. My code throws an InvalidDataException although I know that the data I am passing has been correctly processed by the DEFLATE algorithm (it has been tested). Am I using the DeflateStream incorrectly? My code is as follows:

public byte[] Inflate(byte[] deflateArr)
    {
        MemoryStream ms;

        // try to create a MemoryStream from a byte array
        try
        {
            ms = new MemoryStream(deflateArr);
        }
        catch (ArgumentNullException)
        {
            return null;
        }

        // create a deflatestream and pass it the memory stream
        DeflateStream ds;
        try
        {
            ds = new DeflateStream(ms, CompressionMode.Decompress);
        }
        catch (ArgumentNullException)
        {
            return null;
        }
        catch (ArgumentException)
        {
            return null;
        }

        // create a bytes array and read into it
        byte[] bytes = new byte[4096];

        try
        {
            ds.Read(bytes, 0, 4096);
        }
        catch (ArgumentNullException)
        {
            return null;
        }
        catch (InvalidOperationException)
        {
            return null;
        }
        catch (ArgumentOutOfRangeException)
        {
            return null;
        }
        catch (InvalidDataException)
        {
            return null;
        }

        // close the memory stream
        ms.Close();

        // close the deflate stream
        ds.Close();

        return bytes;
    }
Was it helpful?

Solution

No, you're not.

Things wrong with this code:

  • Explicitly calling Close() instead of using a using statement. Probably not harmful here, but a bad idea.
  • Catching various exceptions which you really shouldn't be catching at all, as they indicate programming bugs
  • Catching exceptions on a per-statement basis, even though you're treating them the same way throughout the code (so could catch the exceptions for a much larger block)
  • Ignoring the return value of Stream.Read

Here's a better version, assuming you're using .NET 4 (for Stream.CopyTo)

public static byte[] Inflate(byte[] inputData)
{
    using (Stream input = new DeflateStream(new MemoryStream(inputData),
                                            CompressionMode.Decompress))
    {
        using (MemoryStream output = new MemoryStream())
        {
            input.CopyTo(output);
            return output.ToArray();
        }
    }
}

Now you may want to catch InvalidDataException - personally I wouldn't at this point, but it may make sense to do so. (I'd catch it at the calling side, if necessary. You can always wrap this method in another one if necessary.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top