DeflateStream不使用从PHP实现处理的缓冲区

时间:2013-04-20 15:24:08

标签: c# .net compression deflate

我正在尝试解压缩由php deflate实现压缩的缓冲区。这是代码:

    public static void CopyTo(Stream src, Stream dest)
    {
        byte[] bytes = new byte[4096];

        int cnt, i = 0;

        while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0 )
        {
            dest.Write(bytes, 0, cnt);
        }
        dest.Flush();
    }

    public static byte[] Unzip(byte[] bytes)
    {
        using (var msi = new MemoryStream(bytes))
        using (var mso = new MemoryStream())
        {
            using (var gs = new DeflateStream(msi, CompressionMode.Decompress))
            {

                msi.ReadByte();
                msi.ReadByte();
                CopyTo(gs, mso);
            }

            return mso.ToArray();
        }
    }

正如您所注意到的,我正在从源流中读取前2个字节,否则DeflateStream会抛出异常,表示无效的块大小。但是,我的问题是,对于某些文件,此代码的工作方式类似于魅力,但对于其他文件,它会提供损坏的结果(仅包含文件某些部分的文件。给人的印象是它没有解压缩整个文件)。任何人都知道什么是错的?

由于

更新

我发现用于压缩数据的PHP函数。这是gzcompress

1 个答案:

答案 0 :(得分:1)

您没有说出您使用的是什么PHP功能,但我猜是gzcompress()。这会生成zlib格式,这是一种原始的deflate格式,其中包含zlib标头和预告片,而DeflateStream期待没有标题或预告片的原始deflate。这就是为什么你必须跳过前两个字节,即zlib头。

PHP函数名称非常糟糕且令人困惑,文档也没有多大帮助。这里有三种格式:raw deflate,gzip-wrapped deflate和zlib-wrapped deflate。所有PHP函数都以gz开头,但只有部分函数实际处理gzip格式。

有时有效,有时可能不是由于行尾或其他文字转换。确保您正在读取文件中的实际字节而不会损坏。