在Java中有效压缩10-1000个字符的字符串?

san*_*ity 8 java compression

我需要将10到1000个字符的字符串(用已知但可变的语言编写)压缩成单独的UDP数据包.

Java中可用的哪些压缩算法非常适合此任务?

是否有可用的开源Java库?

小智 9

"这取决于".

我将从主要候选人开始:LZMA("7-zip"),deflate(直接,zlib:deflate +小包装,gzip:deflate +稍大的包装,zip:deflate +甚至更大的包装),bzip2(我怀疑这将是一个很好的在这里,最好与一个相对大的窗口),也许甚至其他LZ*分支像LZS之一,它有一个IP负载压缩的RFC,但......

...使用几种不同的方法,根据实际数据和压缩/吞吐量运行一些分析.Java有 GZIPOutputStream("deflate in gzip wrapper")和 DeflaterOutputStream("plain deflate",推荐使用gzip或zip"wrappers")标准,还有 LZMA Java实现(只需要压缩器,而不是容器)所以这些都应该是微不足道的模拟.

如果数据包之间存在规律性,则可以使用它 - 例如构建高速缓存映射,霍夫曼表,或者仅修改其他算法之一的"窗口" - 但是数据包丢失和"可压缩性" "可能需要考虑.沿着这条路走下去会增加更多的复杂性.有关帮助压缩器的更多想法可以在SO上找到:如何在处理给定的数据集时为zlib'setDictionary'找到一个好的/最佳的字典?.

此外,协议应该可以简单地"退回"零压缩,因为某些[特别小的随机]数据可能实际上不可压缩或可能"压缩"到更大的大小(zlib实际上有这个保护,但也有"包装器开销"因此,对于非常小的数据,它将更好地单独编码).对于如此小的尺寸,压缩数据的"包装器"(例如gzip或zip)的开销也需要考虑在内.考虑小于约100个字符的字符串数据,这一点尤其重要.

快乐的编码.


另一件需要考虑的事情是用于将字符推入输出流的编码.我首先从UTF-8开始,但这可能并不总是理想的.


请参阅SO:针对短文本字符串的最佳压缩算法,这表明SMAZ,但我不知道该算法将如何转换为unicode/binary.


还要考虑并非所有deflate(或其他格式)实现都是相同的.就小数据的效率而言,与第三方(比如JZlib)相比,我并不知道Java的标准deflate ,但考虑压缩小负载[.NET],它显示"相同压缩"格式的相当负数.文章也很好地结束了:

...无论如何压缩通常是最有益的,并确定哪个有效载荷(压缩的或未压缩的)具有最小的大小并包括一个小的令牌以指示是否需要解压缩.

我的最终结论是:总是使用真实世界的数据进行测试并测量好处,或者最终你可能会有点意外!

快乐的编码.真的这次.


MeB*_*Guy 5

最简单的方法是在ByteArrayOutputStream之上层叠GZIPOutputStream,因为它内置在JDK中,使用

ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream zos = new GZIPOutputStream(baos);

zos.write(someText.getBytes());
zos.finish();
zos.flush();


byte[] udpBuffer = baos.toByteArray();
Run Code Online (Sandbox Code Playgroud)

可能还有其他算法做得更好,但我先尝试一下,看它是否符合你的需求,因为它不需要任何额外的罐子,并且做得非常好.


Pet*_*rey 5

对于少量数据,大多数标准压缩算法都不能很好地工作.通常有一个标题和一个校验和,压缩需要一些时间进行预热.即它根据它看到的数据构建数据字典.

出于这个原因,你可以找到它

  • 小包可以更小或相同大小而不压缩.
  • 一个简单的应用程序/协议特定压缩更好
  • 您必须为压缩算法提供预构建的数据字典,并尽可能地删除标题.

我通常选择小数据包的第二个选项.