【问题标题】:How to correctly implement LZ4, Snappy or equivalent compression techniques in Java?如何在 Java 中正确实现 LZ4、Snappy 或等效压缩技术?
【发布时间】:2023-08-18 10:27:01
【问题描述】:

我尝试将 Java 版本的 LZ4 实现到一种搜索引擎类型的程序中,试图从大型文本文件中搜索数据。我只是压缩了输出流并将其存储到 txt 文件或没有名称的文件中。然而,我意识到所谓的压缩文件并没有缩小,反而比原始文件还要大。

最后我不得不求助于 zip4j,因为它对我有用。

我想知道如何使用 LZ4 或 Snappy 的 jar 来正确压缩/解压缩?

另外,我如何使用这样的算法来压缩一个文件夹,里面有很多文件?

谢谢!

【问题讨论】:

  • 您尝试了什么但没有成功?从概念上讲,您只需使用提供压缩的 OutputStream 包装 FileOutputStream,然后写入该流。如果您正在编写文本,您可能希望使用 OutputStreamWriter 或 PrintWriter 将其包装起来。 oss.sonatype.org/service/local/repositories/releases/archive/…

标签: java compression snappy lz4


【解决方案1】:

我遇到了类似的问题。我试图通过本地网络以 8192 字节的块发送一个大文件(〜 709 MB)。我使用 Lz4 压缩/解压缩来减少网络带宽。

因此,假设您正在尝试做类似的事情,这是我的建议:

这是您可以在https://github.com/jpountz/lz4-java 上找到的类似常规示例的 sn-p

private static int decompressedLength;
private static LZ4Factory factory = LZ4Factory.fastestInstance();
private static LZ4Compressor compressor = factory.fastCompressor();

public static byte[] compress(byte[] src, int srcLen) {
    decompressedLength = srcLen;
    int maxCompressedLength = compressor.maxCompressedLength(decompressedLength);
    byte[] compressed = new byte[maxCompressedLength];
    compressor.compress(src, 0, decompressedLength, compressed, 0, maxCompressedLength);
    return compressed;
}

现在,如果您按原样返回 压缩 字节数组,那么它的长度很可能大于原始 未压缩 数据。

所以你可以修改如下:

private static int decompressedLength;
private static LZ4Factory factory = LZ4Factory.fastestInstance();
private static LZ4Compressor compressor = factory.fastCompressor();

public static byte[] compress(byte[] src, int srcLen) {
    decompressedLength = srcLen;
    int maxCompressedLength = compressor.maxCompressedLength(decompressedLength);
    byte[] compressed = new byte[maxCompressedLength];
    int compressLen = compressor.compress(src, 0, decompressedLength, compressed, 0, maxCompressedLength);
    byte[] finalCompressedArray = Arrays.copyOf(compressed, compressLen);
    return finalCompressedArray;
}

compressLen 存储实际压缩长度,finalCompressedArray 字节数组(长度为compressLen)存储实际压缩数据。一般来说,它的长度小于压缩字节数组和原始未压缩字节数组

的长度

现在您可以按以下常规方式解压缩 finalCompressedArray 字节数组:

private static LZ4FastDecompressor decompressor = factory.fastDecompressor();

public static byte[] decompress(byte[] finalCompressedArray, int decompressedLength) {
    byte[] restored = new byte[decompressedLength];
    restored = decompressor.decompress(finalCompressedArray, decompressedLength);
    return restored;
}

【讨论】:

  • 抱歉来晚了!
  • @Ankit-如果不知道解压后字节数组的大小,解压后的长度是多少?
【解决方案2】:

.jar 文件是 .zip 文件。 zip 文件格式不支持 LZ4 或 Snappy。

【讨论】:

  • 糟糕,错误的问题! :P 我的意思是如何使用 LZ4 或 Snappy 来压缩大文本文件
最近更新 更多