繁体   English   中英

Java 中的冗长字符串压缩/解压缩

[英]Lengthy string compression/decompression in Java

我正在寻找字符串长度压缩以避免冗长的文件名,如下所示。 该字符串还包含 UTF-8 字符。

“dt=20200623_isValid=valid_module_name=A&B&C_data_source=internet_part-00001-1234-9d12-1234-123d-1234567890a1.b001.json”

尝试从 GitHub here进行 Huffman 压缩,它减小了大小,但对字符串长度的影响不大。

压缩前尺寸:944

压缩后尺寸:569

压缩字符串:

请告知如何在 Java 中实现长度压缩? (进一步处理需要解压后的文件名值)。

您应该尝试 ZLIB/GZ 压缩。 你可以在这里找到 GZ 压缩片段java 中的字符串数据的压缩和解压缩

ZLIB 压缩实现也相当容易。 您可以使用以下代码作为入门并对其进行改进。

压缩详解zlib、gzip 和 zip 有什么关系? 它们有什么共同点,又有何不同?

在继续之前阅读 Deflator 策略: Java Deflater 策略 - DEFAULT_STRATEGY、FILTERED 和 HUFFMAN_ONLY

public void compressFile(String originalFileName, String compressedFileName) {
    try (FileInputStream fileInputStream = new FileInputStream(originalFileName);
         FileOutputStream fileOutputStream = new FileOutputStream(compressedFileName);
        DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(fileOutputStream))
    {
        int data;
        while ((data = fileInputStream.read()) != -1) {
            deflaterOutputStream.write(data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

您可以使用 Inflator 解压。

public void decompressFile(String fileTobeDecomporessed, String outputfile) {
    try (
            FileInputStream fileInputStream = new FileInputStream(fileTobeDecomporessed);
            FileOutputStream fileOutputStream = new FileOutputStream(outputfile);
            InflaterInputStream inflaterInputStream = new InflaterInputStream(fileInputStream)) {
        int data;
        while ((data = inflaterInputStream.read()) != -1) {
            fileOutputStream.write(data);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

参考: http://cr.openjdk.java.net/~iris/se/11/latestSpec/api/java.base/java/util/zip/Deflater.html

当然,每个二进制数字使用一个字符会占用大量空间。 该库使用 16 位(字符的大小)来表示单个位,因此它实际上使其结果比它需要的大 16 倍。

一种更简洁的表示二进制数据的方法是将其转换为十六进制

byte[] compressedBytes = new BigInteger(compressedString, 2).toByteArray();

Formatter formatter = new Formatter();
for (byte b : compressedBytes) {
    formatter.format("%02x", b);
}
String hex = formatter.toString();

那么结果是 142 字节:

BE7C7477591F1A1B231E8AFCAC7A28DA85B8E0356B41F9AFCF7E8156F30991727483E95F026A1E1D4C9F17777494C7DC582CC14C7DC531F5298FBB5D9B36E15CD38EEEE9C79

您甚至可以进一步 go 并Base64 对其进行编码,将结果减少到 96 个字节:

String s = Base64.getEncoder().encodeToString(compressedBytes);

结果:

AL58dHdZHxobIx6K/Kx6KNqFuOA1a0H5r89+gVbzCZFydIPpXwJqHh1Mnxd3dJTH3FgswUx9xTH1KY+7XZs24c047u6cd5kV

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM