1

Eclipse 给我以下资源泄漏警告是否有原因:资源泄漏:'br' is never closed"?我正在谈论的代码在这篇文章的底部。

我认为我的 finally 块已经涵盖了所有内容,我的推理:

  • res 只有在 FileInputStream 构造函数抛出时才为空,因此无需关闭任何内容
  • 如果 InputStreamReader 构造函数抛出, res 将是输入流(例如格式错误的编码字符串),然后只有 InputStream 必须关闭,所以可以
  • ETC...

那么我错过了什么?或者这可能是一个日食错误?

亲切的问候!

S。

public static String fileToString(String fileName, String encoding) throws IOException {
    InputStream is;
    InputStreamReader isr;
    BufferedReader br;
    Closeable res = null;
    try {
        is = new FileInputStream(fileName);
        res = is;
        isr = new InputStreamReader(is, encoding);
        res = isr;
        br = new BufferedReader(isr);
        res = br;
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            builder.append(line);
            builder.append(LS);
        }
        return builder.toString();
    } finally {
        if (res != null) {
            res.close();
        }
    }
}
4

1 回答 1

5

Eclipse 可能只是不理解您对res变量所做的改组。

我建议使用 try-with-resources 语句(在 Java 7 及更高版本中可用,现在已经三年半了),它极大地简化了这些类型的链:

public static String fileToString(String fileName, String encoding) throws IOException {

    try (
        InputStream is = new FileInputStream(fileName);
        InputStreamReader isr = new InputStreamReader(is, encoding);
        BufferedReader br = new BufferedReader(isr)
    ) {
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            builder.append(line);
            builder.append(LS);
        }
        return builder.toString();
    }
}

如果您不能使用 try-with-resources,您可能需要类似 Apache CommonsIOUtils类的closeQuietly方法(字面意思是那个方法,或者您自己的方法),而不是res四处走动,这读起来很尴尬,而且我敢说容易出现维护问题。

使用IOUtils可能如下所示:

public static String fileToString(String fileName, String encoding) throws IOException {
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;

    try {
        is = new FileInputStream(fileName);
        isr = new InputStreamReader(is, encoding);
        br = new BufferedReader(isr)
        StringBuilder builder = new StringBuilder();
        String line = null;
        while ((line = br.readLine()) != null) {
            builder.append(line);
            builder.append(LS);
        }
        br.close();
        return builder.toString();
    }
    finally {
        IOUtils.closeQuietly(br, isr, is);
    }
}

请注意我如何close在.tryfinally

但是 try-with-resources 是更好的答案,因为它更简洁并且与新的(ish)“抑制异常”的东西挂钩。


旁注:没有理由= null初始化line,您在下一行分配它。

旁注2:如果文件可能是任何大小,请考虑提前找出它有多大并StringBuilder在构造函数中设置容量。StringBuilder的默认容量是 16,因此即使是几百字节的文件也会涉及到StringBuilder的内部缓冲区的多次重新分配。

于 2014-11-27T15:15:15.373 回答