我想知道下面的代码是否正确地关闭了finally块中的InputStream
InputStream is = new FileInputStream("test");
try {
for(;;) {
int b = is.read();
...
}
} finally {
try {
is.close();
} catch(IOException e) {
}
}
Run Code Online (Sandbox Code Playgroud)
如果在is.close()期间发生异常,则在is.read()期间发生异常将被忽略/抑制吗?
Alp*_*dar 15
最好的方法是使用Java 7并使用try with resources,或者手动执行相同的操作,并在关闭时添加异常作为抑制异常.
Pre Java 7:如果你抛出自定义异常,你可以在它中添加压缩异常,就像它在Java 7中完成一样(在你的异常创建字段列表中被禁止并在关闭操作中放置异常,并在处理异常时,查看那里如果你不能这样做,我不知道什么比记录它更好.
示例:来自Java教程
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
Run Code Online (Sandbox Code Playgroud)
但更好的形式是:
static String readFirstLineFromFile(String path) throws IOException {
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
Run Code Online (Sandbox Code Playgroud)
这种方式即使FileReader的创建成功但BufferedReader的创建失败(例如内存不足),FileReader也将被关闭.
您可以使用来自https://commons.apache.org/proper/commons-io/的 IOUtils关闭它
public void readStream(InputStream ins) {
try {
//do some operation with stream
} catch (Exception ex) {
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(ins);
}
}
Run Code Online (Sandbox Code Playgroud)
如果try块的执行由于任何其他原因R突然完成,则执行finally块.然后有一个选择:如果finally块正常完成,那么try语句突然完成原因R.如果finally块突然完成原因S,则try语句突然完成原因S(并且原因R被丢弃).
所以你是对的,你会失去原来的例外.
解决方案可能是如此防御地编写你的finally块,如果finally块失败,那么它是一个更大的惊喜(值得传播),而不是try catch块出现异常.
因此,例如,如果在您尝试关闭它时该流可能为null,请检查它:
InputStream is = new FileInputStream("test");
try {
for(;;) {
int b = is.read();
...
}
} finally {
try {
if( is!=null ) {
is.close();
}
} catch(IOException e) {
}
}
Run Code Online (Sandbox Code Playgroud)
在Java 7中,Alpedar的解决方案当然是必由之路.
| 归档时间: |
|
| 查看次数: |
19929 次 |
| 最近记录: |