0

我对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 字节的字节数组的方式,但我不知道压缩后的数据会有多大。我在这里做错了什么?我该如何解决?

4

2 回答 2

1

如果您不想写整个数组,而是只写由Deflateruse填充的部分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();
}

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


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

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

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

于 2013-08-07T10:26:49.407 回答
0

您将所有 100 个字节的数组写入文件compressed,但您必须只写入 deflater 返回的真正压缩的字节。 int compressedsize = compresser.deflate(compressed);
fos.write(compressed, 0, compressedsize);

于 2013-08-07T10:28:10.247 回答