我对Java完全陌生,因此我决定通过在Java中做一个小项目来学习它。我需要使用zlib压缩一些字符串并将其写入文件。但是,文件太大。这是代码示例:

String input = "yasar\0yasar"; // test input. Input will have null character in it.
byte[] compressed = new byte[100];  // hold compressed content

Deflater compresser = new Deflater();
compresser.setInput(input.getBytes());
compresser.finish();
compresser.deflate(compressed);
File test_file = new File(System.getProperty("user.dir"), "test_file");
try {
    if (!test_file.exists()) {
        test_file.createNewFile();
    }
    try (FileOutputStream fos = new FileOutputStream(test_file)) {
        fos.write(compressed);
    }
} catch (IOException e) {
    e.printStackTrace();
}


这将写入一个1 KB的文件,而该文件最多应为11个字节(因为此处的内容为11个字节)。我认为问题出在我将压缩为100个字节的字节数组初始化的方式上,但是我不知道预先计算的数据将有多大。我在这里做错了什么?我该如何解决?

最佳答案

如果您不想编写整个数组,而只写由Deflater填充的部分,请使用OutputStream#write(byte[] array, int offset, int lenght)

大致像

String input = "yasar\0yasar"; // test input. Input will have null character in it.
byte[] compressed = new byte[100];  // hold compressed content

Deflater compresser = new Deflater();
compresser.setInput(input.getBytes());
compresser.finish();
int length = compresser.deflate(compressed);
File test_file = new File(System.getProperty("user.dir"), "test_file");
try {
    if (!test_file.exists()) {
        test_file.createNewFile();
    }
    try (FileOutputStream fos = new FileOutputStream(test_file)) {
        fos.write(compressed, 0, length); // starting at 0th byte - lenght(-1)
    }
} catch (IOException e) {
    e.printStackTrace();
}


在Windows中,您可能仍然会看到1kB或类似的内容,因为您看到的内容似乎是四舍五入的(您之前写了100个字节),或者它指的是文件系统上的大小至少为1 block大(应该为4kb IIRC)。右键单击该文件,然后检查属性中的大小,该大小应显示实际大小。



如果您事先不知道大小,请不要使用Deflater,而是使用DeflaterOutputStream写入任何压缩长度的数据。

try (OutputStream out = new DeflaterOutputStream(new FileOutputStream(test_file))) {
    out.write("hello!".getBytes());
}


上面的示例将使用默认值进行缩小,但您可以在Deflater的构造函数中传递已配置的DeflaterOutputStream来更改行为。

关于java - Zlib压缩太大,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18100573/

10-13 01:17