在最终块中断 zip 中复制 ByteStream 后关闭 GZIPOutputStream
Closing GZIPOutputStream after ByteStream copy in finally block break zip
我有压缩和解压缩文本的代码。我遇到了奇怪的行为——只有当我在某个地方关闭 GZIPOutputStream
时,代码才有效,但是当我尝试将 GZIPOutputStream close
放在 finally 块中时,它会中断并且不起作用。如果将 : gzipoutputstream.close()
放在放置注释的 czip
函数中,它将起作用。但是,如果您只将它保留在 finally
块中,它就会中断。为什么?
ByteStreams.copy
函数来自 com.google.common.io guava
public class Main {
public static byte[] dzip(byte[] s) throws IOException {
ByteArrayInputStream sStream = null;
ByteArrayOutputStream oStream = null;
InputStream gzipoutputStream = null;
ByteBuffer arrReturn = null;
try {
sStream = new ByteArrayInputStream(s);
oStream = new ByteArrayOutputStream();
gzipoutputStream = new GZIPInputStream(sStream, 1024);
ByteStreams.copy(gzipoutputStream, oStream);
arrReturn = ByteBuffer.wrap(oStream.toByteArray());
}
catch (Exception e) {
return null;
} finally {
if (gzipoutputStream != null) {
gzipoutputStream.close();
}
if (oStream != null) {
oStream.close();
}
if (sStream != null) {
sStream.close();
}
}
return arrReturn.array();
}
public static byte[] czip(byte[] s) throws IOException {
ByteArrayInputStream sStream =null;
ByteArrayOutputStream oStream =null;
OutputStream gzipoutputstream = null;
byte[] returnValue = null;
try {
sStream = new ByteArrayInputStream(s);
oStream = new ByteArrayOutputStream(s.length / 2);
gzipoutputstream = new GZIPOutputStream(oStream, 1024);
ByteStreams.copy(sStream, gzipoutputstream);
//////////// ------------------------------------ \\\\\\
//gzipoutputstream.close(); // < --- Works only when placed here
//////////// ------------------------------------ \\\\\\
returnValue = oStream.toByteArray(); // Here the zip is 000
}catch(Exception e) {
return null;
} finally {
if (gzipoutputstream != null) {
gzipoutputstream.close();
}
if (oStream != null) {
oStream.close();
}
if (sStream != null) {
sStream.close();
}
}
return returnValue;
}
public static void main(String[] args) throws IOException {
String s = "12313dsfafafafaf";
byte[] source = (byte[]) s.getBytes();
byte[] returnZipByteArr = czip(source);
byte[] dd = dzip(returnZipByteArr);
String ss = new String(dd);
System.out.println(ss);
}
}
这是意料之中的。 The javadoc of close() 说:
Writes remaining compressed data to the output stream and closes the underlying stream.
因此,如果您尝试在调用 close() 之前访问 ByteArrayOutputStream() 中的字节,则 gzip 压缩尚未完成:GZIP 流需要知道不会再将任何内容写入到正确写入剩余数据。
您可以调用 finish()
来获得相同的效果,但不会关闭流(因此仍然会在 finally 块中关闭它)。
我有压缩和解压缩文本的代码。我遇到了奇怪的行为——只有当我在某个地方关闭 GZIPOutputStream
时,代码才有效,但是当我尝试将 GZIPOutputStream close
放在 finally 块中时,它会中断并且不起作用。如果将 : gzipoutputstream.close()
放在放置注释的 czip
函数中,它将起作用。但是,如果您只将它保留在 finally
块中,它就会中断。为什么?
ByteStreams.copy
函数来自 com.google.common.io guava
public class Main {
public static byte[] dzip(byte[] s) throws IOException {
ByteArrayInputStream sStream = null;
ByteArrayOutputStream oStream = null;
InputStream gzipoutputStream = null;
ByteBuffer arrReturn = null;
try {
sStream = new ByteArrayInputStream(s);
oStream = new ByteArrayOutputStream();
gzipoutputStream = new GZIPInputStream(sStream, 1024);
ByteStreams.copy(gzipoutputStream, oStream);
arrReturn = ByteBuffer.wrap(oStream.toByteArray());
}
catch (Exception e) {
return null;
} finally {
if (gzipoutputStream != null) {
gzipoutputStream.close();
}
if (oStream != null) {
oStream.close();
}
if (sStream != null) {
sStream.close();
}
}
return arrReturn.array();
}
public static byte[] czip(byte[] s) throws IOException {
ByteArrayInputStream sStream =null;
ByteArrayOutputStream oStream =null;
OutputStream gzipoutputstream = null;
byte[] returnValue = null;
try {
sStream = new ByteArrayInputStream(s);
oStream = new ByteArrayOutputStream(s.length / 2);
gzipoutputstream = new GZIPOutputStream(oStream, 1024);
ByteStreams.copy(sStream, gzipoutputstream);
//////////// ------------------------------------ \\\\\\
//gzipoutputstream.close(); // < --- Works only when placed here
//////////// ------------------------------------ \\\\\\
returnValue = oStream.toByteArray(); // Here the zip is 000
}catch(Exception e) {
return null;
} finally {
if (gzipoutputstream != null) {
gzipoutputstream.close();
}
if (oStream != null) {
oStream.close();
}
if (sStream != null) {
sStream.close();
}
}
return returnValue;
}
public static void main(String[] args) throws IOException {
String s = "12313dsfafafafaf";
byte[] source = (byte[]) s.getBytes();
byte[] returnZipByteArr = czip(source);
byte[] dd = dzip(returnZipByteArr);
String ss = new String(dd);
System.out.println(ss);
}
}
这是意料之中的。 The javadoc of close() 说:
Writes remaining compressed data to the output stream and closes the underlying stream.
因此,如果您尝试在调用 close() 之前访问 ByteArrayOutputStream() 中的字节,则 gzip 压缩尚未完成:GZIP 流需要知道不会再将任何内容写入到正确写入剩余数据。
您可以调用 finish()
来获得相同的效果,但不会关闭流(因此仍然会在 finally 块中关闭它)。