我需要将10到1000个字符的字符串(用已知但可变的语言编写)压缩成单独的UDP数据包。
Java中可用的哪些压缩算法非常适合此任务?
是否有可用的开源Java库?
答案 0 :(得分:9)
“这取决于”。
我会从主要候选人开始:LZMA(“7-zip”),deflate(直接,zlib:deflate +小包装,gzip:deflate +略大的包装,zip: deflate +甚至更大的包装器),bzip2(我怀疑这在这里会很好,最适合相对较大的窗口),甚至可能是LZS之类的其他LZ *分支has an RFC for IP Payload compression但是......
...使用多种不同方法,根据实际数据和压缩/吞吐量 运行一些分析。 Java有GZIPOutputStream(“gzip包装中的deflate”)和DeflaterOutputStream(“普通deflate”,推荐使用gzip或zip“wrappers”)标准,并且有LZMA Java implementations(只需要压缩器) ,而不是容器)所以这些都应该是模拟的小事。
如果数据包之间存在规律性,那么可以使用它 - 例如构建缓存映射,Huffman表,或者仅修改其他算法之一的“窗口” - 但可能需要考虑数据包丢失和“解压缩”。通过走这条路线会增加更多的复杂性。有关帮助压缩机的更多想法可以在SO: How to find a good/optimal dictionary for zlib 'setDictionary' when processing a given set of data?找到。
此外,协议应该可以简单地“退回”零压缩,因为某些[特别小的随机]数据可能实际上不可压缩或可能"compress" to a larger size(zlib实际上有这种保护,但也有“包装器开销”,因此对于非常小的数据,它将更好地单独编码)。对于如此小的尺寸,压缩数据的“包装器”(例如gzip或zip)的开销也需要考虑在内。考虑到小于约100个字符的字符串数据,这一点尤为重要。
快乐的编码。
要考虑的另一件事是用于将字符推入输出流的编码。我首先从UTF-8开始,但这可能并不总是理想的。
请参阅SO: Best compression algorithm for short text strings建议SMAZ,但我不知道此算法将如何转移到unicode / binary。
还要考虑并非所有deflate(或其他格式)实现都是相同的。就小数据的效率而言,与第三方(比如JZlib)相比,我并不知道Java的标准deflate,但考虑Compressing Small Payloads [.NET]显示“相同压缩”格式的相当负数。文章也很好地结束了:
...无论如何压缩通常是最有益的,并确定哪个有效负载(压缩的或未压缩的有效负载)具有最小的大小,并包含一个小的令牌来指示是否需要解压缩。
我的最终结论:始终使用真实世界的数据进行测试并衡量效益,或者最终您可能会有点意外!
快乐的编码。这次是真的。
答案 1 :(得分:5)
最简单的方法是将一个GZIPOutputStream层叠在ByteArrayOutputStream之上,因为它是内置在JDK中的,使用
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);
zos.write(someText.getBytes());
zos.finish();
zos.flush();
byte[] udpBuffer = baos.toByteArray();
可能还有其他算法可以做得更好,但我先尝试一下,看看它是否符合您的需求,因为它不需要任何额外的罐子,并且做得非常好。
答案 2 :(得分:5)
大多数标准压缩算法在使用少量数据时效果不佳。通常有一个标题和一个校验和,压缩需要一些时间进行预热。即它根据已经看到的数据构建数据字典。
因此你可以找到
我通常选择小数据包的第二个选项。
答案 3 :(得分:1)
短字符串/ 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。
upd:base64实现在这里:http://www.source-code.biz/base64coder/java 你必须改变它以使网址安全,即更改以下字符: