转载1:
Java IO流关闭问题的深入研究
转载2:
Java IO包装流如何关闭?(关闭顺序)
两种分析过程不一样,但是结论相差不大:
(个人认为转载1分析的比较透彻)
一般情况下是:先打开的后关闭,后打开的先关闭;
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常;
(1)JAVA的IO流使用了装饰模式,关闭最外面的流的时候会自动调用被包装的流的close()方吗?
(2)如果按顺序关闭流,是从内层流到外层流关闭还是从外层到内存关闭?
问题(1)解释:
如下例子代码:
FileInputStream is = new FileInputStream(".");
BufferedInputStream bis = new BufferedInputStream(is);
bis.close();
从设计模式上看:
java.io.BufferedInputStream是java.io.InputStream的装饰类。
BufferedInputStream装饰一个 InputStream 使之具有缓冲功能,is要关闭只需要调用最终被装饰出的对象的 close()方法即可,因为它最终会调用真正数据源对象的 close()方法。
BufferedInputStream的close方法中对InputStream进行了关闭,下面是jdk中附带的源代码:
java.io.BufferedInputStream的api:
close
public void close()throws IOException 关闭此输入流并释放与该流关联的所有系统资源。
因此,可以只调用外层流的close方法关闭其装饰的内层流,验证例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
bw.write("java IO close test");
bw.close();
问题(2)解释:如果不想使用(1)方式关闭流,可以逐个关闭流(可能大家比较习惯吧)
如下例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt")
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8")
BufferedWriter bw = new BufferedWriter(osw)
bw.write("java IO close test")
//从内带外顺序顺序会报异常
fos.close()
osw.close()
bw.close()
报出异常:
Exception in thread "main" java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:26)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:99)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.close(BufferedWriter.java:246)
at com.my.test.QQ.main(QQ.java:22)
如下例子:
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("d:\\a.txt")
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8")
BufferedWriter bw = new BufferedWriter(osw)
bw.write("java IO close test")
// 从外到内顺序关闭ok
bw.close()
osw.close()
fos.close()
一般情况下是:先打开的后关闭,后打开的先关闭
另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b
例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
如果将节点流关闭以后再关闭处理流,会抛出IO异常;
转载1:Java IO流关闭问题的深入研究 转载2:Java IO包装流如何关闭?(关闭顺序)两种分析过程不一样,但是结论相差不大: (个人认为转载1分析的比较透彻)一般情况下是:先打开的后关闭,后打开的先关闭;另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b例如处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b当然完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候
Java中关闭流一直是个让人头疼的问题,很多人要么就是忘记关闭,要么就是对关闭的顺序模糊不清,实际开发过程中,也常常因为流未关闭导致应用程序出现各种莫名奇妙的Bug。所以本篇整理出了Java中Stream流(主要指IO流,非指Java1.8中流式处理)关闭中常见的几种情况,并通过自己测试和查看源码等方式给出证明过程,下面开始。
1.各种流中存在包装关系,如何关闭
try {
InputStream inputStream = new FileInputStream("D:\\test\\te
包装流是没有无参的,必须传递对应的基础流。完整代码:
之前使用的 IO 流中,都是跟磁盘直接进行交互,这种交互方式效率比较低下。现在使用的是有缓冲区,从磁盘直接读取到内存中,再从内存中一次性读取出来:
看起来这种方式好像更麻烦了,但是这种方式实际效率更高。
2、包装流不关闭资源(close
public static void main(String[] args) throws IOException {
FileOutputStream out = null;
FileInputStream in = null;
BufferedOutputStream bos = null;
BufferedInputStream...
File 类的介绍:http://www.cnblogs.com/ysocean/p/6851878.html
Java IO 流的分类介绍:http://www.cnblogs.com/ysocean/p/6854098.html
Java IO 字节输入输出流:http://www.cnblogs.com/ysocean/p/6854541.html
Java IO 字符输入输出流:https://i.cnblogs.com/EditPosts.aspx?postid=6859242
GC运行的时间点是不确定的(因为是一条单独存在的线程),所以很多时候你不能直接控制什么时候发生GC。
这个带来的问题有两点
一个是`有时候你的内存不足需要立刻回收而GC并不会立刻运行`
另外一个是因为`GC运行期间会占用大量系统资源所以某些情况下你会希望把它推后,或者干脆关掉以便根据性能需求在合式的时候手动执行`。
另外,GC只能回收内存。至于各种stream之类,他们接下来一般还开启了各种其他的系统资源,比如文件,比如输入输出设备(键盘/屏幕等),等等。
而这些设备第一是不能自