开发者社区 问答 正文

关于java中关闭流疑问

下面这段代码的作用是压缩,会用到ZipOutputStream

  ZipOutputStream zipOutputStream = null;
    try {
      zipOutputStream = new ZipOutputStream(new FileOutputStream(zipPath));
    } catch (FileNotFoundException e) {
        throw new IllegalArgumentException("zipPath error " + "", e);
    } finally {
        if (null != zipOutputStream) {
            try {
                zipOutputStream.close();
            } catch (IOException e) {
                logger.error("", e);
            }
        }
    }

错误放大版1:

 ZipOutputStream zipOutputStream = null;
    try {
        FileOutputStream fileOutputStream =   new FileOutputStream(zipPath);
        throw new RuntimeException();
        zipOutputStream = new ZipOutputStream(fileOutputStream);
    } catch (FileNotFoundException e) {
        throw new IllegalArgumentException("zipPath error " + "", e);
    } finally {
        if (null != zipOutputStream) {
            try {
                zipOutputStream.close();
            } catch (IOException e) {
                logger.error("", e);
            }
        }
    }

错误放大版2:

    ZipOutputStream zipOutputStream = null;
    try {
      zipOutputStream = new ZipOutputStream(new FileOutputStream(zipPath),null);
    } catch (FileNotFoundException e) {
        throw new IllegalArgumentException("zipPath error " + "", e);
    } finally {
        if (null != zipOutputStream) {
            try {
                zipOutputStream.close();
            } catch (IOException e) {
                logger.error("", e);
            }
        }
    }

这里我有一个疑问,在new FileOutputStream(zipPath)的过程中如果已经打开了这个文件,但是在new ZipOutputStream过程中出错了,这个时候zipOutputStream并没有创建成功,所以在finally中不会调用close方法,造成的结果就是这个文件不会被关闭。
所以这种关闭方式是不是会有漏洞,还是我的理由有问题?

展开
收起
蛮大人123 2016-03-10 12:00:54 2018 分享 版权
1 条回答
写回答
取消 提交回答
  • 我说我不帅他们就打我,还说我虚伪

    这个例子有漏洞,不过漏洞不在这里,而是 FileOutputStream。
    如果 new ZipOutputStream()调用失败,这个构造方法会抛出运行时异常,而且不会关闭传递进来的 FileOutputStream 对象。
    由于调用者也不持有该对象的引用,也无法释放资源,会造成打开的文件描述符没有关闭。
    如果使用java8的话可以用 try with,或者在finally块里面释放FileOutputStream 对象持有的资源,这样是比较保险的做法。

    2019-07-17 18:57:24
    赞同 展开评论
问答分类:
问答标签:
问答地址: