【问题标题】:.NET DeflateStream Usage.NET DeflateStream 用法
【发布时间】:2012-07-02 14:03:52
【问题描述】:

我正在尝试使用 DeflateStream 在 .NET 中使用 INFLATE 压缩流。我的代码抛出了一个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;
    }

【问题讨论】:

    标签: .net inflate deflate deflatestream


    【解决方案1】:

    不,你不是。

    这段代码有问题:

    • 显式调用Close() 而不是使用using 语句。在这里可能没有害处,但这是个坏主意。
    • 捕获您真正根本不应该捕获的各种异常,因为它们表明存在编程错误
    • 基于每个语句捕获异常,即使您在整个代码中以相同的方式处理它们(因此可以捕获更大块的异常)
    • 忽略Stream.Read的返回值

    这是一个更好的版本,假设您使用的是 .NET 4(对于 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();
            }
        }
    }
    

    现在你可能想赶上InvalidDataException - 我个人现在不会,但这样做可能是有意义的。 (如有必要,我会在调用方捕获它。如有必要,您始终可以将此方法包装在另一个方法中。)

    【讨论】:

    • 对不起,这是一个愚蠢的问题,但是捕获异常有什么缺点?
    • @cytinus:它隐藏了一个错误。如果您的方法返回 null,那么您不知道为什么,并且您的程序将继续运行 - 而如果异常冒泡,您可以告诉您有错误,并且您不要尝试继续处理不良数据。像ArgumentNullException 这样的东西应该总是由于某个地方的错误 - 所以你想尽快找到那个错误。
    • 哦,我的实际代码包含一堆日志记录,如果该方法返回 null,则调用方法会以错误消息杀死程序。一切都记录到 Windows 事件记录器中,我刚刚从问题中删除了该代码,因为它与我的问题无关。
    • 也是DefaultStream,你的意思是DeflateStream吗?
    • @cytinus:是的,DefaultStream 是一个错字。但是添加所有这些 catch 块仍然是一个非常糟糕的主意。让异常冒泡到堆栈顶部然后将其记录在中心位置并在必要时终止程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    相关资源
    最近更新 更多