5

GZIPOutputStream在我的java程序中使用压缩大字符串,最后将它存储在数据库中。

我可以看到,在压缩英文文本时,我实现了 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();
4

2 回答 2

2

JavaGZIPOutputStream使用Deflate压缩算法来压缩数据。Deflate 是LZ77Huffman 编码的组合。根据 Unicode 的压缩常见问题解答

问:使用标准压缩算法(例如 Huffman 编码或 LZW 的无专利变体)有什么问题?

答:SCSU 通过消除作为编码一部分的额外冗余(每隔一个字节的序列相同)而不是内容中的冗余,弥补了基于 8 位的 LZW 和 16 位编码的 Unicode 文本之间的差距. SCSU 的输出应发送到 LZW 以在需要的地方进行块压缩。

为了使用一种流行的通用算法(如 Huffman 或 Lempel-Ziv 压缩的任何变体)获得相同的效果,它必须重新定位到 16 位,由于较大的字母大小而失去有效性。计算霍夫曼案例的数学运算相对容易,以显示压缩文本需要多少额外位,因为字母表更大。LZW 也存在类似的效果。有关一般文本压缩问题的详细讨论,请参阅Bell、Cleary 和 Witten所著的Text Compression一书(Prentice Hall 1990)。

我能够在 unicode 网站上找到这组用于 SCSU 压缩的 Java 类,这可能对您有用,但是我找不到可以轻松导入到项目中的 .jar 库,尽管您可能可以将它们打包如果您愿意,可以合二为一。

于 2014-04-11T13:56:25.207 回答
0

我不太懂中文,但据我所知,GZIP 压缩依赖于重复的文本序列,而这些重复序列会随着“描述”而改变(这是一个非常高级的解释)。这意味着如果您在字符串中的 20 个位置有一个单词“library”,则算法会将单词“library”存储在旁边,然后注意它应该出现在位置 x、y、z 上......所以,你可能不会原始字符串中有很多冗余,因此您无法节省很多。相反,您的开销大于节省。

我不是真正的压缩专家,也不知道细节,但这是压缩的基本原理。

PS这个问题可能只是重复:为什么gzip压缩缓冲区大小大于未压缩缓冲区?

于 2014-04-11T13:51:10.937 回答