我有一个从文件中读取文本的方法;可能需要解压缩,具体取决于输入参数:
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块中逐个关闭它们?
非常感谢。
答案 0 :(得分:3)
是的,关闭最外面的流/阅读器就足够了。
但是,您的代码还有另一个潜在的错误:new InputStreamReader(in)
将使用平台默认编码,这取决于操作系统区域/语言设置。您应该指定文本文件的编码并在构造函数中显式使用它。
答案 1 :(得分:2)
这里有一点要补充:在调用'in.close()'之前看看'in'是否为null,因为如果没有第一个赋值成功就会发生异常。
此外,仅捕获可能的异常(例如IOException)是一种很好的形式。这样,如果您添加更多代码并且IDE告诉您未处理新的异常类型,您可以添加适当的特定代码而不是从未听过它,因为最初用于IOException的catch(异常)也是(错误处理? )其他所有类型。
答案 2 :(得分:0)
这是干净的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()。