java - 在finally block 中断zip中的ByteStream复制后关闭GZIPOutputStream

标签 java stream zlib gzipoutputstream

我有压缩和解压缩文本的代码。我面临奇怪的行为 - 仅当我在某个地方关闭 GZIPOutputStream 时,代码才有效,但是当我尝试将 GZIPOutputStream close 放在finally block 中时,它会中断并且不起作用。如果您将:gzipoutputstream.close() 放在放置注释的czip 函数中,它将起作用。但是,如果您仅将其保留在finally block 中,它将崩溃。为什么?

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 block 中关闭它)。

关于java - 在finally block 中断zip中的ByteStream复制后关闭GZIPOutputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55790261/

相关文章:

java - 如何将对象序列化到java中的非阻塞套接字

java - GWT DMP 插件崩溃

java - 通过键盘在 JTable 中按下 JButton

delphi - 使用(winsock 的)recv 接收时 TStringStream 被损坏?

C++ 菜鸟(流)...如何从字符串有空格的文件中读取字符串(例如,Tom Smith)?使用 getline 而不是 >> 时遇到问题

c# - 在 Python 中压缩 在 C# 中解压

java - 如何使用实现特定接口(interface)的对象声明一个 LinkedList?

windows - 无法在 Python (Windows) 中安装镜像包 - 需要 zlib

git - 在命令行中解压zlib文件

c# - asp.net mvc生成数据下载文件