.NET zlib Stream与Actionscript ByteArray.uncompress兼容

Jos*_*gry 6 .net c# apache-flex actionscript-3 .net-3.5

我似乎无法获得Flex 3想要解压缩的流.

我试过了:

  • System.IO.Compression.GZipStream
  • System.IO.Compression.DeflateStream
  • ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream
  • zlib.ZOutputStream

这些似乎都没有让人ByteArray.uncompress高兴,即我得到了

错误#2058:解压缩数据时出错.

整个Deflate vs zlib让我绕圈子走了.

似乎根据维基百科的文章,zlib是DEFLATE的一个实现.但根据Actionscript他们是两个不同的东西?

微软也似乎预示着Gzip已至少使用deflate算法,在他们的文档,他们指的是GZipOutputStream使用相同的压缩算法DeflateStream.所以我假设它只是一个头的区别,这表明这是"没有好"至于"ByteArray.uncompress"为使用"deflate"算法在AIR应用程序仅支持.

示例"服务器"代码,在这种情况下使用SharpZipLib(不工作):

    public virtual bool ProcessRequest(string path, HttpListenerContext context)
    {
        var buffer = File.ReadAllBytes(path);
        // Specifying to strip header/footer from data as that seems to be what the
        // docs for ByteArray.uncompress indicate is necessary 
        var deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true); 
        using (var zipStream = new DeflaterOutputStream(context.Response.OutputStream, deflater))
        {
            zipStream.Write(buffer, 0, buffer.Length);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Che*_*eso 11

ZLIB和DEFLATE不一样.IETF RFC中定义了一组3个相关的压缩规范:

它们都(主要)使用特定的压缩算法,即DEFLATE.

ZLIB如何与DEFLATE相关联

第一个是ZLIB,包括开头的帧字节.根据RFC 1950 ...

  A zlib stream has the following structure:

       0   1
     +---+---+
     |CMF|FLG|   (more-->)
     +---+---+

  (if FLG.FDICT set)

       0   1   2   3
     +---+---+---+---+
     |     DICTID    |   (more-->)
     +---+---+---+---+

     +=====================+---+---+---+---+
     |...compressed data...|    ADLER32    |
     +=====================+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)

CMF和FLG是字节.正如规范所说,ZLIB中使用的主要压缩方法是DEFLATE,尽管规范可以与其他方法一起使用.一般情况下不是.此外,通常使用DICTID .因此,每个ZLIB字节流都有2个字节,后跟压缩数据流,然后是Adler32校验和.压缩数据是来自DEFLATE的裸字节流.

GZIP如何与DEFLATE相关

这样可以解决ZLIB与DEFLATE的不同之处.GZIP是第三种格式.如果您需要详细信息,请查看RFC.关键是像ZLIB一样,GZIP主要使用DEFLATE,它在压缩数据流之前放置一个标头,然后是校验和.但是GZIP头与ZLIB头不同,因此任何GZipStream类都不能编写可以作为ZLIB读取的字节流.反之亦然.

解决问题

读取 ZLIB Stream时,有些人在将流推进前两个ZLIB成帧字节后解决了在数据流上使用.NET的内置DeflateStream所遇到的问题.这是有效的,只要您想要READ,ZLIB流使用DEFLATE(安全假设)并且它不定义固定字典(也非常安全),如果您不关心Adler32提供的完整性检查(也许).

如果您不喜欢做出这些假设或放弃检查,或者您必须生成一个 ZLIB数据流,DotNetZip中的ZlibStream将为您读取和写入ZLIB数据流,并根据需要验证或生成校验和.

DotNetZip可以免费使用,适用于任何.NET语言.您不需要完整的DotNetZip库,而只需要Ionic.Zlib.dll.