今天做了个涉及到资源流关闭的需求,其中使用到了BufferReader流。
try{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
System.out.println("Enter some text:");
String line = br.readLine();
System.out.println("You entered: " + line);
} catch (IOException e) {
e.printStackTrace();
}
上面这段代码是InputStreamReader和BufferedReader的常见用法,但值得注意的是,在结束使用时,我们要对这些资源流进行关闭,否则可能会造成内存资源消耗,导致OOM错误。通常的做法是在finally块中对资源进行关闭。
BufferedReader br = null;
try {
InputStreamReader isr = new InputStreamReader(System.in);
br = new BufferedReader(isr);
System.out.println("Enter some text:");
String line = br.readLine();
System.out.println("You entered: " + line);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
上述代码是我之前采用的写法。后来经过相关资料的查询,发现在finally块中只需关闭br即可,即可以替换成以下写法。
BufferedReader br = null;
try {
InputStreamReader isr = new InputStreamReader(System.in);
br = new BufferedReader(isr);
System.out.println("Enter some text:");
String line = br.readLine();
System.out.println("You entered: " + line);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
为什么不需要对InputStreamReader流进行关闭呢,这是因为BufferedReader流中close方法的源代码中已经对原生InputStreamReader流进行了判断,以下是该方法的源码:
//BufferedReader中的close方法源码
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
try {
in.close();//这里的in就是原生流
} finally {
in = null;
cb = null;
}
}
}
其中in对象就是原生InputStreamReader流,它在调用BufferedReader类中的构造方法时进行了赋值。
经过进一步查资料得知,BufferedReader属于Java中的装饰流,什么是装饰流呢?装饰流是指通过装饰模式实现的java流,又称为包装流,装饰流只是为原生流附加额外的功能(或效果),除此以外,桥接流也属于装饰流。
装饰流关闭时通常会对原生流也进行关闭,有这样层层关闭的机制,我们就只需要关闭最外层的流就行了,对于上述例子来说,关闭BufferedReader流即可。
在这里给大家推荐一篇博客,感觉博主总结的很好,一起学习~
关于Java中流关闭以及先后顺序等问题总结_bufferedreader关闭流的顺序-CSDN博客