我在java程序中使用GZIPOutputStream
压缩大字符串,最后将其存储在数据库中。
我可以看到,在压缩英文文本时,我实现了1/4到1/10的压缩比(取决于字符串值)。所以说例如我的原始英文文本是100kb,那么平均压缩文本将在30kb左右。
但是当我压缩unicode字符时,压缩字符串实际上占用的字节数比原始字符串多。比方说,我的原始unicode字符串是100kb,然后压缩版本是200kb。
Unicode字符串示例:"嗨,这是,短信计数测试持续for.Hi这是短"
有人可以建议我如何实现unicode文本的压缩?为什么压缩版本实际上比原始版本大?
我在Java中的压缩代码:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write(text.getBytes("UTF-8"));
zos.finish();
zos.flush();
byte[] udpBuffer = baos.toByteArray();
答案 0 :(得分:1)
Java GZIPOutputStream
使用Deflate压缩算法压缩数据。 Deflate是LZ77和Huffman coding的组合。 According to Unicode's Compression FAQ:
问:使用标准压缩算法(如霍夫曼编码或LZW的无专利变体)有什么问题?答:SCSU通过消除作为编码一部分的额外冗余(每隔一个字节的序列相同)而不是冗余来弥补基于8位的LZW和16位编码的Unicode文本之间的差距。在内容中。应该将SCSU的输出发送到LZW以进行块压缩。
为了与一种流行的通用算法(如Huffman或Lempel-Ziv压缩的任何变体)获得相同的效果,它必须重新定位到16位,由于字母大小较大而失去效力。为霍夫曼案例计算数学是相对容易的,以显示压缩文本需要多少额外位,因为字母表更大。 LZW也存在类似的效果。有关一般文本压缩问题的详细讨论,请参阅Bell,Cleary和Witten的书 Text Compression (Prentice Hall 1990)。
我能够在unicode网站上找到this set of Java classes进行SCSU压缩,这可能对您有用,但我找不到一个可以轻松导入项目的.jar库,尽管你可以如果你愿意,可以将它们打包成一个。
答案 1 :(得分:0)
我真的不懂中文,但据我所知,GZIP压缩依赖于重复的文本序列,而那些重复序列随着“描述”而改变(这是一个非常高级别的解释)。这意味着如果你在一个字符串中的20个位置有一个单词“library”,算法将在侧面存储单词“library”,并注意它应该出现在x,y,z的位置......所以,你可能不会原始字符串中有很多冗余,因此无法节省很多。相反,你有更多的开销而不是储蓄。
我不是真正的压缩专家,我不知道细节,但这是压缩的基本原理。
P.S 这个问题可能只是重复:Why gzip compressed buffer size is greater then uncompressed buffer?