【问题标题】:FindBugs - "may fail to close stream" when using ObjectOutputStreamFindBugs - 使用 ObjectOutputStream 时“可能无法关闭流”
【发布时间】:2013-01-21 07:46:12
【问题描述】:

我有这段代码,就是写一个Ojbect到一个字节数组流中:

     static byte[] toBytes(MyTokens tokens) throws IOException {
        ByteArrayOutputStream out = null;
        ObjectOutput s = null;
        try {
            out = new ByteArrayOutputStream();
            try {
                s = new ObjectOutputStream(out);
                s.writeObject(tokens);
            } finally {
                try {
                    s.close();
                } catch (Exception e) {
                    throw new CSBRuntimeException(e);
                }             
            }
        } catch (Exception e) {
            throw new CSBRuntimeException(e);
        } finally {
            IOUtils.closeQuietly(out);
        }
        return out.toByteArray();
    }

但是,FindBugs 一直在抱怨 line:

s = new ObjectOutputStream(out);

“可能无法关闭流” - BAD_PRACTICE - OS_OPEN_STREAM。有人可以帮忙吗?

【问题讨论】:

  • 如果你使用的是Java 7,你可以使用try-with-resources
  • 不幸的是,我被 Java 6 困住了
  • 仅供参考 - 我无法让我的 FindBugs 抱怨您的代码。我正在使用最新的 FindBugs Eclipse,报告级别设置为 20(最不相关)并启用每个类别。您使用的是哪个版本的 FindBugs,您是如何执行它的?
  • 我使用 Eclipse 3.7 和 Maven,因此使用了 findbugs-maven-plugin:2.5.2。使用“mvn site”运行它以报告错误。

标签: java stream findbugs software-quality


【解决方案1】:

我认为 FindBugs 并不理解 IOUtils.closeQuietly(out) 关闭。

无论如何,关闭 ObjectOutputStream 就足够了,它会关闭底层的 ByteArrayOutputStream。这是 ObjectOutputStream.close 实现

public void close() throws IOException {
    flush();
    clear();
    bout.close();
}

这样你就可以简化你的代码

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ObjectOutputStream s = new ObjectOutputStream(out);
    try {
        s.writeObject(1);
    } finally {
        IOUtils.closeQuietly(s);
    }

或者如果您使用的是 Java 7

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    try (ObjectOutputStream s = new ObjectOutputStream(out)) {
        s.writeObject(1);
    }

【讨论】:

  • 我已经试过了,但是 IOUtils.closeQuietly() 不能与 ObjectOutput 一起工作,所以它不能关闭“s”。它只允许 OutputStream...
  • 再试一次。有用。 ObjectOutputStream 扩展了 OutputStream 所以它是 OutputStream
  • 我不这么认为:“找不到符号符号:方法 closeQuietly(java.io.ObjectOutput) 位置:类 org.apache.commons.io.IOUtils”
  • 也许“s”被定义为 ObjectOutput 类型导致这个
  • 对,直接使用ObjectOutputStream,ObjectOutput是一个接口
【解决方案2】:

这意味着s.close() 将尝试关闭底层流,但它可能会失败。所以要确保你也应该自己关闭它。尝试添加out.close(),看看警告是否消失。

【讨论】:

  • FindBugs 肯定会突出显示out = new ByteArrayOutputStream(); 行吗?
  • 它突出显示行s = new ObjectOutputStream(out);,因为它里面是out.close()。这只是一个警告,它可能导致错误。如果该行不存在,他将看不到任何警告。
猜你喜欢
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 2014-07-20
  • 2012-09-04
  • 1970-01-01
  • 2010-09-28
  • 2017-09-07
  • 1970-01-01
相关资源
最近更新 更多