关闭顺序
根据API可知
调用 close() 方法是关闭该流并释放与之关联的所有资源。在关闭该流后,再调用 read()、ready()、mark()、reset() 或 skip() 将抛出 IOException。关闭以前关闭的流无效。
- 互不关联的IO流:先打开的后关闭,后打开的先关闭。开的时候先读再写,关的时候先写再读
- 含依赖关系IO流:如流a依赖流b,应该先关闭流a,再关闭流b
偷懒
- 完全可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法
- 如果将节点流关闭以后再关闭处理流,会抛出 IO 异常
测试
FileOutputStream fos = new FileOutputStream(“test.txt”);
OutputStreamWriter osw = new OutputStreamWriter(fos, “UTF-8″);
BufferedWriter bw = new BufferedWriter(osw);
- 下面这种关闭顺序会报异常: java.io.IOException: Stream closed
fos.close(); osw.close(); bw.close();
- 下面这种关闭顺序则不会报异常
bw.close(); osw.close(); fos.close();
使用场景
按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。
节点流
可以从或向一个特定的地方(节点)读写数据。如 FileReader
- 文件:
FileInputStream
FileOutputStrean
FileReader
FileWriter
文件进行处理的节点流 - 数组:
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组) - 字符:
StringReader
StringWriter
对字符串进行处理的节点流 - 管道:
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
对管道进行处理的节点流
处理流
是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如 BufferedReader
。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
- 缓冲流:
BufferedImputStrean
BufferedOutputStream
BufferedReader
BufferedWriter
需要父类作为参数构造,增加缓冲功能,避免频繁读写硬盘,可以初始化缓冲数据的大小,由于带了缓冲功能,所以就写数据的时候需要使用 flush 方法咯 - 转换流:
InputStreamReader
OutputStreamWriter
要InputStream
或OutputStream
作为参数,实现从字节流到字符流的转换 - 数据流:
DataInputStream
DataOutputStream
提供将基础数据类型写入到文件中,或者读取出来,为什么要有这个流呢?看这样的分析,如果没有这种流的话,有一个 long,本身只占 8 个字节,如果我要写入到文件,需要转成字符串,然后在转成字符数组,那空间会占用很多,但是有了这种流之后就很方便了,直接将这 8 个字节写到文件就完了。。是不是既节约了内存空间有让程序写起来更加方便简单了呐。写倒是很简单,但是读取的时候就注意了,根据读取的数据类型,指针会往下移,所以你写的顺序必须要和读的顺序一致才能完成你正确的需求