.NET DeflateStream使用情况

.NET DeflateStream使用情况,.net,inflate,deflate,deflatestream,.net,Inflate,Deflate,Deflatestream,我正在尝试使用DeflateStream在.NET中使用充气压缩流。我的代码抛出一个InvalidDataException,尽管我知道我传递的数据已经被DEFLATE算法正确处理(它已经过测试)。我是否错误地使用了DeflateStream?我的代码如下: public byte[] Inflate(byte[] deflateArr) { MemoryStream ms; // try to create a MemoryStream from a

我正在尝试使用
DeflateStream
在.NET中使用充气压缩流。我的代码抛出一个
InvalidDataException
,尽管我知道我传递的数据已经被DEFLATE算法正确处理(它已经过测试)。我是否错误地使用了
DeflateStream
?我的代码如下:

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;
    }
不,你不是

此代码有问题:

  • 显式调用
    Close()
    ,而不是使用
    语句。在这里可能没什么害处,但这是个坏主意
  • 捕获各种您根本不应该捕获的异常,因为它们表示编程错误
  • 在每个语句的基础上捕获异常,即使在整个代码中以相同的方式处理它们(因此可以捕获更大块的异常)
  • 忽略流的返回值。读取
这里有一个更好的版本,假设您使用的是.NET4(用于
Stream.CopyTo

现在您可能想捕获
InvalidDataException
——就个人而言,我现在不想这样做,但这样做可能有意义。(如果有必要,我会在调用端捕获它。如果有必要,您可以随时将此方法包装到另一个方法中。)

不,您不是

此代码有问题:

  • 显式调用
    Close()
    ,而不是使用
    语句。在这里可能没什么害处,但这是个坏主意
  • 捕获各种您根本不应该捕获的异常,因为它们表示编程错误
  • 在每个语句的基础上捕获异常,即使在整个代码中以相同的方式处理它们(因此可以捕获更大块的异常)
  • 忽略流的返回值。读取
这里有一个更好的版本,假设您使用的是.NET4(用于
Stream.CopyTo


现在您可能想捕获
InvalidDataException
——就个人而言,我现在不想这样做,但这样做可能有意义。(如果有必要,我会在调用端捕获它。如果有必要,您可以随时将此方法包装到另一个方法中。)

如果这是一个愚蠢的问题,很抱歉,但是捕获异常的缺点是什么?@cytinus:它隐藏了一个错误。如果您的方法返回null,您不知道为什么,并且您的程序将继续运行-然而,如果出现异常,您可以判断您有错误,并且您不会继续使用坏数据。类似于
ArgumentNullException
的东西应该总是由于某个bug引起的-因此您希望尽快找到该bug。哦,我的实际代码包含大量日志记录,如果该方法返回null,则调用方法将以错误消息终止程序。所有内容都记录到Windows事件记录器中,我只是从问题中删除了该代码,因为它与我的问题无关。另外,
DefaultStream
您的意思是
DeflaTestStream
?@cytinus:是的,
DefaultStream
是一个打字错误。但是,添加所有这些捕获块仍然是一个非常糟糕的主意。让异常冒泡到堆栈顶部,然后将其记录到中心位置,并在必要时终止程序。如果这是一个愚蠢的问题,很抱歉,但是捕获异常的缺点是什么?@cytinus:它隐藏了一个bug。如果您的方法返回null,您不知道为什么,并且您的程序将继续运行-然而,如果出现异常,您可以判断您有错误,并且您不会继续使用坏数据。类似于
ArgumentNullException
的东西应该总是由于某个bug引起的-因此您希望尽快找到该bug。哦,我的实际代码包含大量日志记录,如果该方法返回null,则调用方法将以错误消息终止程序。所有内容都记录到Windows事件记录器中,我只是从问题中删除了该代码,因为它与我的问题无关。另外,
DefaultStream
您的意思是
DeflaTestStream
?@cytinus:是的,
DefaultStream
是一个打字错误。但是,添加所有这些捕获块仍然是一个非常糟糕的主意。让异常冒泡到堆栈顶部,然后将其记录到中心位置,并在必要时终止程序。
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();
        }
    }
}