我需要将长度在10到1000个字符之间的字符串(使用已知但可变语言编写)压缩为单独的UDP数据包。
有哪些适合这项任务的Java压缩算法?
也许有开源的Java库可以完成这个任务吗?
我需要将长度在10到1000个字符之间的字符串(使用已知但可变语言编写)压缩为单独的UDP数据包。
有哪些适合这项任务的Java压缩算法?
也许有开源的Java库可以完成这个任务吗?
"这要看情况而定"。
我会先从主要的候选方案开始考虑: LZMA(“7-zip”),deflate(直接使用,zlib:deflate + 小包装,gzip:deflate + 稍大的包装,zip:deflate + 更大的包装),bzip2(我觉得在这里可能不太好用,适合于相对较大的窗口),甚至其他LZ*分支之一,如有用于IP Payload压缩的LZS,但是...
...根据实际数据和压缩/吞吐量运行一些分析使用几种不同的方法。Java具有GZIPOutputStream(“gzip包装中的deflate”)和DeflaterOutputStream(“普通deflate”,推荐使用比gzip或zip“包装”更好)的标准,还有LZMA Java实现(只需要压缩器,不需要容器),因此这些都应该很容易模拟。
如果数据包之间存在规律,那么可以利用这些规律,例如构建缓存映射、Huffman表,或只改变另一个算法的“窗口”,但需要考虑数据包丢失和“解压缩性”。但是采用这种方法会增加更多复杂性。有关如何帮助压缩器的更多想法可在SO: 如何在处理给定数据集时为zlib 'setDictionary'找到良好/最优字典?中找到。同时需要考虑到并非所有的deflate(或其他格式)实现都是相同的。我不清楚Java标准的deflate与第三方工具(比如JZlib)在处理小数据方面的效率差别,但请参考压缩小负载[.NET]这篇文章,其中显示“相同压缩”格式的结果非常糟糕。这篇文章也有一个很好的结论:
......通常来说最好还是进行压缩,并确定哪个有效负载(压缩或未压缩的)具有最小的大小,并包含一个小记号以指示是否需要解压缩。
我的最终结论:始终使用真实数据进行测试并衡量好处,否则你最终可能会有点惊喜!
愉快的编码。这次可是真的。
最简单的方法是在ByteArrayOutputStream上使用GZIPOutputStream进行分层,因为它已经内置于JDK中,使用方式如下:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write(someText.getBytes());
zos.finish();
zos.flush();
byte[] udpBuffer = baos.toByteArray();
可能有其他算法做得更好,但我建议先尝试这个,看看它是否符合您的需求,因为它不需要任何额外的jar包,并且表现相当不错。
DeflaterOutputStream
或GZipOutputStream
中的任何一个。 - Lawrence Dol对于短字符串/ URL 的良好压缩算法是 LZW 实现,它在 Java 中,并且可以轻松移植到客户端 GWT: https://code.google.com/p/lzwj/source/browse/src/main/java/by/dev/madhead/lzwj/compress/LZW.java
一些备注
我正在使用它来对客户端 GWT 中的复杂 URL 参数进行编码,以及与 Base64 编码和 Autobean 序列化为 JSON 一起使用。
更新:base64 实现在这里:http://www.source-code.biz/base64coder/java 你需要将其改为 url 安全的,即更改以下字符: