java:我需要关闭所有流吗?

发布于 2024-11-07 13:13:22 字数 984 浏览 2 评论 0原文

我有一个从文件中读取文本的方法;可能需要解压,具体取决于输入参数:

public static String readText(File inFile, boolean compressed) {
    InputStream in = null;
    InputStreamReader isr = null;
    StringBuilder sb = new StringBuilder();//constant resizing is costly, so set the STRING_SIZE
    try {
        in = new FileInputStream(inFile);
        if (compressed) {
            in = new GZIPInputStream(in);
        }
        isr = new InputStreamReader(in);
        int length = 0;
        char[] cbuf = new char[8 * 1024];
        while ((length = isr.read(cbuf)) != -1) {
            sb.append(cbuf, 0, length);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            in.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    return sb.toString();
}

有人建议我像这样使用InputStream,这样更容易编写,所以最后我只需要关闭一件事。我还是有点担心这可能会导致内存泄漏。所以我的问题是:有谁知道上面的代码是否可以?或者我是否必须返回一打流并在finally块中将它们一一关闭?

多谢。

I have a method that reads text from a file; decompression may be required, depending on an input parameter:

public static String readText(File inFile, boolean compressed) {
    InputStream in = null;
    InputStreamReader isr = null;
    StringBuilder sb = new StringBuilder();//constant resizing is costly, so set the STRING_SIZE
    try {
        in = new FileInputStream(inFile);
        if (compressed) {
            in = new GZIPInputStream(in);
        }
        isr = new InputStreamReader(in);
        int length = 0;
        char[] cbuf = new char[8 * 1024];
        while ((length = isr.read(cbuf)) != -1) {
            sb.append(cbuf, 0, length);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            in.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    return sb.toString();
}

It was suggested that I use InputStream like this so it is easier to write, and so that in the end I only have to close one thing. I am still a bit worried this might cause a memory leak. So my question is: does anyone knows if the code above is OK? Or do I have to get back to a dozen of streams and close them one by one in a finally block?

Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧话新听 2024-11-14 13:13:22

是的,关闭最外面的流/读取器就足够了。

但是,您的代码还有另一个潜在的错误:new InputStreamReader(in) 将使用平台默认编码,这取决于操作系统区域/语言设置。您应该指定文本文件的编码并在构造函数中显式使用它。

Yes, closing the outermost stream/reader is sufficient.

However, your code has another potential bug: new InputStreamReader(in) will use the platform default encoding, which depends on the OS region/language settings. You should specify the encoding of the text file and use it explicitly in the constructor.

陈独秀 2024-11-14 13:13:22

这里有一点需要补充:在调用 'in.close()' 之前查看 'in' 是否为 null,因为在第一次分配成功的情况下可能会发生异常。

另外,仅捕获可能的异常(例如 IOException)也是一种很好的形式。这样,如果您添加更多代码并且 IDE 告诉您未处理新的异常类型,您可以添加适当的特定代码,而不是从未听说过它,因为最初用于 IOException 的 catch (Exception ) 也是(错误处理? )所有其他类型。

Here's one point to add: see if 'in' is null before calling 'in.close()' as the exception could happen without the first assignment succeeding.

Also, it's good form to only catch possible exceptions (e.g. IOException). That way if you add more code and the IDE tells you that a new exception type isn't handled you can add the proper specific code rather than never hearing about it because the catch (Exception ) which was originally for IOException is also (mishandling?) every other type.

如若梦似彩虹 2024-11-14 13:13:22

这是干净的 Java 7 方法,适用于任何实现 AutoCloseable/Closeable 的方法:

try (InputStream in = compressed ?
                        new GZIPInputStream(new FileInputStream(inFile))
                      : new FileInputStream(inFile);
     InputStreamReader isr = new InputStreamReader(in))
{
    int length = 0;
    char[] cbuf = new char[8 * 1024];
    while ((length = isr.read(cbuf)) != -1) {
        sb.append(cbuf, 0, length);
    }
}
catch (Exception e) {
    e.printStackTrace();
}

如果您想知道关闭资源时出现异常会发生什么,请阅读还添加的 getSuppressedExceptions() 。

Here's the clean Java 7 way which works for anything that implements AutoCloseable/Closeable:

try (InputStream in = compressed ?
                        new GZIPInputStream(new FileInputStream(inFile))
                      : new FileInputStream(inFile);
     InputStreamReader isr = new InputStreamReader(in))
{
    int length = 0;
    char[] cbuf = new char[8 * 1024];
    while ((length = isr.read(cbuf)) != -1) {
        sb.append(cbuf, 0, length);
    }
}
catch (Exception e) {
    e.printStackTrace();
}

If you're wondering what happens if there's an exception while closing the resource, read about getSuppressedExceptions() which was also added.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文