一:分类
分类维度复杂交错是初学者对于I/O流头疼的地方,虽然下面会列举一些分类解释,但是不建议查看。学习I/O流根据输入输出、字节字符两个方向进行就OK
- 方向:根据文件传输起始地址划分为输入、输出流,程序读取磁盘文件内容称之为输入、向磁盘文件写入内容称之为输出
- 单位:根据处理文件内容每次的单位划分为字节、字符流,字节流也就每次处理单个字节、字符流每次处理单位为字符
- 内容:文件内容可能有字符串、对象、基本数据、图片、影视等,其中就可以分为对象流、数据流、数组流等,提一点就是音乐、图片等只能使用字节流处理
- 频率:操作磁盘的频率太高性能肯定会遭到影响,这样就衍生出缓冲流
- 转换:字节流想转换为字符流就需要使用到转换流进行中间转换
二:字节输入
本节内容以下讲解的所有I/O流都是以字节为单位操作的输入流
2.1 结构示意图
2.2 文件输入FileInputStream
- 流读取操作read三个方法重载,注释比较清晰。提一点就是这三个方法由InputStrea定义,即所有字节输入流都有其实现
- 其它操作就包括关闭close、大概判断总共读取字节数available等基本操作
2.3 Byte数组输入ByteArrayInputStream
操作与FileInputStream一致,其数据来源与FileInputStream有所区别。FileInputStream数据来源与文件,而ByteArrayInputStream数据来源于byte数组
2.4 对象输入ObjectInputStream
其实说白了就是针对对象操作的流,需要说的就是如果使用特定数据类型的read方法必须保证类型正确,不然会抛出EOFException异常
2.5 缓冲输入 BufferedInputStream
操作上没有差异,主要是缓冲流内部维护一个byte数组,该数组用于一次访问磁盘后缓存读取字节,避免频繁的磁盘访问。构造时可以限定该数组大小,默认大小8M
2.6 数据输入 DataInputStream
个人感觉这个流没啥用,毕竟它可以完成的工作ObjectInputStream也可以完成的很好。与对象流一致需要注意的点就是读取数据的时候一定要注意数据的类型是否正确,不正确抛出异常EOFException
2.7 字节输入流总结
FileInputStream与ByteArrayInputStream都是作为与数据源直接交互的介质流存在,差距在于数据源类型的区别,前者是文件后者是数组
ObjectInputStream、BufferedInputStream、DataInputStream都可以说是一种装饰者类型,构造都需要介质流。通过装饰实现后能针对不同的数据完成不同的优化使用以及特定功能
三:转换流
字节流有点就是可以处理所有类型的数据源,字符流优点就是快呀。当处理文本数据时想要使用字符流,字符流的基础就是字节流,想要通过字节流转换到字符流就需要转换流的操作。输入转换流InputSreamReader、输出转换流OutputStreamWriter
四:字符输入
五:字节输出
六:字符输出
七:输入、输出总结
前面就详细讲解了一个字节输入流,剩下的都是给了一个结构示意图。确实没有必要再浪费时间篇幅重复描述,字节与字符就是将input换为Reader、output换为Writer,输入与输出就是将in换为out、Reader换为Writer
针对数组操作的流在字符操作中就是CharArrayReader与CharArrayWriter
StringReader与StringWriter都是针对字符串操作的字节流,为了格式统一画在了字符流中。在这里提出解释,其操作如下所示
八:管道流
记得在多线程基础文章中讲过这个管道流,可以用于不同线程之间的通信,形成类似于管道的操作
8.1 管道连接
除了上图所示定义输出流时指定输入流,还可以在定义输入流时指定输出流
当然,如果在实例化管道流时并不想指定与其连接的管道流。可以通过下图所示方法进行连接,即管道流提供的connect方法
8.2 阻塞消费
当管道中不存在数据时,如果管道输出流进行消费则会线程阻塞等待管道输入流注入数据