Gzip解压缩会添加一个额外的字节...为什么?

4

我写了一个简单的Java代码片段,它将字符串转换为byte[],然后使用Gzip进行压缩。然后解压结果以获取byte[],其中现在包含一个额外的垃圾值字节。为什么会有一个垃圾值字节?

public static void main(String[] args) throws Exception {

String testString = "Sample String here";
byte[] originalBytes = testString.getBytes();

ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(originalBytes);
gzos.close();

byte[] compressedBytes = baos.toByteArray();

ByteArrayInputStream bais = new ByteArrayInputStream(compressedBytes);
GZIPInputStream gzis = new GZIPInputStream(bais);

ByteArrayOutputStream dbaos = new ByteArrayOutputStream();
while(gzis.available() > 0) {
    dbaos.write(gzis.read());
}
byte[] decompressedBytes = dbaos.toByteArray();
String decompressedString = new String(decompressedBytes);

System.out.println(">>" + decompressedString + "<<");
System.out.println("Size of bytes before: " + originalBytes.length);
System.out.println("Size of bytes after: " + decompressedBytes.length);

输出:

>>Sample String here�<<
Size of bytes before: 18
Size of bytes after: 19

有人能告诉我为什么会出现垃圾值字节吗?如何在不改变上面代码配置的情况下去除它?

1个回答

4

在这里你使用了available(),所以你会得到一个额外的字节。你应该读取流并检查小于0的值。请更改此处。

ByteArrayOutputStream dbaos = new ByteArrayOutputStream();
while(gzis.available() > 0) {
    dbaos.write(gzis.read());
}

转换为类似于以下内容:

ByteArrayOutputStream dbaos = new ByteArrayOutputStream();
int b;
while ((b = gzis.read()) >= 0) {
    dbaos.write(b);
}

而我得到了

>>Sample String here<<
Size of bytes before: 18
Size of bytes after: 18

如果读取的字节是合法的负值,而在我的实际情况中它可能是这样(字符串压缩不是我真正代码中正在做的事情),那该怎么办? - Ahmad
1
这就是为什么read返回一个int。这是你从流中读取直到结束的方法。你的方式会添加一个额外的字节。 - Elliott Frisch
你的意思是说 read 函数会一直返回非负整数,直到读取到文件末尾? - Ahmad
让我们来看一下InputStream.read(),它说(部分内容):返回的值字节是一个范围在0255之间的int 并且它返回数据流中的下一个byte,如果已经到达流的末尾,则返回-1 - Elliott Frisch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接