【问题标题】:GZIP outputs and sizes between C#/dot Net and JavaC#/dot Net 和 Java 之间的 GZIP 输出和大小
【发布时间】:2012-11-15 22:04:21
【问题描述】:


我正在测试在 Java 和 C# 之间压缩一些消息传递的可行性。
使用的消息传递范围从小字符串 (40 字节) 到大字符串 (4K)。

我发现 Java GZIP 实现与 dot Net GZIP 实现的输出存在差异。

我猜 dot Net 的标头更大,导致开销很大。 我更喜欢 Java 实现,因为它在小字符串上效果更好,并且希望 dot Net 也能达到类似的效果。

输出,Java 版本 1.6.0_10

Text:EncodeDecode
Bytes:(12 bytes)RW5jb2RlRGVjb2Rl  <- Base64
Compressed:(29)H4sIAAAAAAAAAHPNS85PSXVJBZEAd9jYdgwAAAA=
Decompressed:(12)RW5jb2RlRGVjb2Rl
Converted:EncodeDecode

Text:EncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecode
Bytes:(120)RW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2Rl
Compressed:(33)H4sIAAAAAAAAAHPNS85PSXVJBZGudGQDAOcKnrd4AAAA
Decompressed:(120)RW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2Rl
Converted:EncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecode

输出,点网 2.0.50727

Text:EncodeDecode
Bytes:(12)RW5jb2RlRGVjb2Rl
Compressed:(128)H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ik6X02qWP83x7/8Dd9jYdgwAAAA=
Decompressed:(12)RW5jb2RlRGVjb2Rl
Text:EncodeDecode

Text:EncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecode
Bytes:(120)RW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2Rl
Compressed:(131)H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Ik6X02qWP83x7w/z9/8H5wqet3gAAAA=
Decompressed:(120)RW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2RlRW5jb2RlRGVjb2Rl
Text:EncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecodeEncodeDecode

如何在 dot Net 端实现更小尺寸的编码?

注意,
Java实现可以解码dot Net实现和
dot Net 实现可以解码 Java 实现。

Java 代码

@Test
public void testEncodeDecode()
{
    final String strTitle = "EncodeDecode";
    try
    {
        debug( "Text:" + strTitle );

        byte[] ba = strTitle.getBytes( "UTF-8" );
        debug( "Bytes:" + toString( ba ) );

        byte[] eba = encode_GZIP( ba );
        debug( "Encoded:" + toString( eba ) );

        byte[] ba2 = decode_GZIP( eba );
        debug( "Decoded:" + toString( ba2 ) );

        debug( "Converted:" + new String( ba2, "UTF-8" ) );
    }
    catch( Exception ex ) { fail( ex ); }
}
@Test
public void testEncodeDecode2()
{
    final String strTitle = "EncodeDecode";
    try
    {
        StringBuilder sb = new StringBuilder();
        for( int i = 0 ; i < 10 ; i++ ) sb.append( strTitle );

        debug( "Text:" + sb.toString() );

        byte[] ba = sb.toString().getBytes( ENCODING );
        debug( "Bytes:" + toString( ba ) );

        byte[] eba = encode_GZIP( ba );
        debug( "Encoded:" + toString( eba ) );

        byte[] ba2 = decode_GZIP( eba );
        debug( "Decoded:" + toString( ba2 ) );

        debug( "Converted:" + new String( ba2, ENCODING ) );
    }
    catch( Exception ex ) { fail( ex ); }
}
private String toString( byte[] ba )
{
    return "("+ba.length+")"+Base64.byteArrayToBase64( ba );
}
protected static byte[] encode_GZIP( byte[] baData ) throws IOException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    ByteArrayInputStream bais = new ByteArrayInputStream( baData );
    GZIPOutputStream zos = new GZIPOutputStream( baos );

    byte[] baBuf = new byte[ 1024 ];
    int nSize;
    while( -1 != ( nSize = bais.read( baBuf ) ) )
    {
        zos.write( baBuf, 0, nSize );
        zos.flush();
    }
    Utilities.closeQuietly( zos );
    Utilities.closeQuietly( bais );
    return baos.toByteArray();
}
protected static byte[] decode_GZIP( byte[] baData ) throws IOException
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    ByteArrayInputStream bais = new ByteArrayInputStream( baData );
    GZIPInputStream zis = new GZIPInputStream( bais );

    byte[] baBuf = new byte[ 1024 ];
    int nSize;
    while( -1 != ( nSize = zis.read( baBuf ) ) )
    {
        baos.write( baBuf, 0, nSize );
        baos.flush();
    }
    Utilities.closeQuietly( zis );
    Utilities.closeQuietly( bais );

    return baos.toByteArray();
}


private void debug( Object o ) { System.out.println( o ); }
private void fail( Exception ex )
{
    ex.printStackTrace();
    Assert.fail( ex.getMessage() );
}

点网代码

    [Test]
    public void TestJava6()
    {
        string strData = "EncodeDecode";
        Console.WriteLine("Text:" + strData);

        byte[] baData = Encoding.UTF8.GetBytes(strData);
        Console.WriteLine("Bytes:" + toString(baData));

        byte[] ebaData2 = encode_GZIP(baData);
        Console.WriteLine("Encoded:" + toString(ebaData2));

        byte[] baData2 = decode_GZIP(ebaData2);
        Console.WriteLine("Decoded:" + toString(baData2));

        Console.WriteLine("Text:" + Encoding.UTF8.GetString(baData2));
    }
    [Test]
    public void TestJava7()
    {
        string strData = "EncodeDecode";

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 10; i++) sb.Append(strData);

        Console.WriteLine("Text:" + sb.ToString());

        byte[] baData = Encoding.UTF8.GetBytes(sb.ToString());
        Console.WriteLine("Bytes:" + toString(baData));

        byte[] ebaData2 = encode_GZIP(baData);
        Console.WriteLine("Encoded:" + toString(ebaData2));

        byte[] baData2 = decode_GZIP(ebaData2);
        Console.WriteLine("Decoded:" + toString(baData2));

        Console.WriteLine("Text:" + Encoding.UTF8.GetString(baData2));
    }
    public string toString(byte[] ba)
    {
        return "(" + ba.Length + ")" + Convert.ToBase64String(ba);
    }
    protected static byte[] decode_GZIP(byte[] ba)
    {
        MemoryStream writer = new MemoryStream();
        using (GZipStream zis = new GZipStream(new MemoryStream(ba), CompressionMode.Decompress))
        {
            Utilities.CopyStream(zis, writer);
        }
        return writer.ToArray();
    }
    protected static byte[] encode_GZIP(byte[] ba)
    {
        using (MemoryStream reader = new MemoryStream(ba))
        {
            MemoryStream writer = new MemoryStream();
            using (GZipStream zos = new GZipStream(writer, CompressionMode.Compress))
            {
                Utilities.CopyStream(reader, zos);
            }
            return writer.ToArray();
        }
    }

【问题讨论】:

  • 你在处理字符串还是字节?向我们展示代码!
  • 代码已添加,感谢您花时间查看。
  • 嗯...起初我认为字符串在两个平台上的编码可能不同(即,不是两个 UTF-8)。但情况似乎并非如此。您是否尝试过具有不同压缩级别的替代构造函数GZipStream(Stream, CompressionLevel, Boolean)?也许 Java 实现只是默认为更好的压缩级别。抱歉,我没有安装 dotnet,所以我无法自己进行实验。
  • 我目前正在使用 dot Net 2.0,压缩级别是不可配置的。我想知道更新到以后的 dot Net 是否会对我的事业有所帮助,但是我没有准备好尝试以后的框架。
  • 我注意到你使用这个循环 StringBuilder sb = new StringBuilder(); for (int i = 0; i

标签: java .net gzip


【解决方案1】:

这是 .NET gzip 代码中的几个错误之一。应该避免该代码。请改用DotNetZip。在这里查看答案:Why does my C# gzip produce a larger file than Fiddler or PHP?

【讨论】:

  • 那是……令人惊讶。我知道 GZip 的实现很糟糕,但我认为它已在 4.0 中修复。感谢您的信息。
  • 为什么会如此惊人?它是由微软编写的。
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
相关资源
最近更新 更多