一、IO 流概述
我们知道存在硬盘中数据是永久保存的,而在内存中的数据只是临时的,内存中的数据可以存入硬盘中,硬盘中的数据也也可以读入内存中。
I/O 是 Input/Output 的缩写, I/O 技术是非常实用的技术, 用于处理设备之间的数据传输。 如读/写文件,网络通讯等。
我们把这种数据的传输,可以看做一种数据的流动,按照流动的方法,以内存为基准,分为
输入 input:流向内存是输入流,从别的地方(文件、键盘、网络、内存等)读取数据到当前程序中。
输出 output:流出内存是输出流,从程序把数据写/输出到文件、屏幕(控制台)、网络、内存等中。
Java程序中,对于数据的输入/输出操作以“流(stream)” 的方式进行。
java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
输入也叫做读取数据,输出也叫做写出数据。
注意:
(1)如果对于 File 对象,输入和输出操作只能针对文件,不能针对目录;
(2)IO操作不仅仅是针对文件,可以从网络中输入和输出。
二、Java 中IO 流原理
输入input: 读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
输出output: 将程序(内存)数据输出到磁盘、光盘等存储设备中。
三、IO 的流向说明图解
四、IO流的分类
(1)按操作数据单位不同分为: 字节流(8 bit),字符流(16 bit)
字节流:以字节(Byte)为单位,读写数据的流。
字符流:以字符(char)为单位,读写数据的流。
区别:字节流适用于读写任何类型的文件。
字符流只能用于读/写纯文本数据,纯文本主要有(txt,html,xml,properties,yml,java,cpp等),如果都读写纯文本文件,字符流快于字节流。
(2)按数据流的流向不同分为: 输入流,输出流
输入流:把数据从其他设备上读取到 内存中的流。
输出流:把数据从 内存 中写出到其他设备上的流。
(3)按流的功能角色的不同分为: 节点流,处理流
节点流:和某个节点关联,如,文件流...等。
处理流:在节点流的基础上,加其他的处理功能,加装饰功能,如,缓冲流,序列化和反序列化等。
节点流:节点流可以从一个特定的数据源(节点)读写数据(如:文件,内存)
处理流:处理流是“连接在已存在的流(节点流或者处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。不直接连接到数据源或目的地,而是“连接” 在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
五、I/O 流的设计
1、IO流的顶级父类
(1)Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。
(2)由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
IO流有四大抽象的父类(超类/基类)
2、设计思想
Java 中 IO 体系是用到了一个装饰者设计模式。
IO 流的设计用了 “装饰者”设计模式,即 IO 流分为两大类,“被修饰” 的组件和 “装饰” 的组件。
例如:以 InputStream 为例
其中 FileInputStream、ByteArrayInputStream 等是 “被装饰” 的组件,依次用来连接和读取“文件”,“内存中的字节数组”等。
而 BufferedInputStream、DataInputStream、ObjectInputStream 等是用来“装饰”的组件,依次是给其他 InputStream 的 IO流提供装饰的辅助功能的,依次可以增加“提高效率的缓冲功能”、“按照Java数据类型读取数据的能力”、“读取并恢复Java对象的能力”等
对于另外的 OutputStream、Reader、Writer 系列的流设计方法也是一样的。
扩展:
装饰模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),其使用一种对客户端透明的方式来动态地扩展对象的功能,它是通过继承扩展功能的替代方案之一。在现实生活中你也有很多装饰者的例子,例如:人需要各种各样的衣着,不管你穿着怎样,但是,对于你个人本质来说是不变的,充其量只是在外面加上了一些装饰,有“保暖的”、“好看的”、“防雨的”....
3、IO流的选取
IO 流的选取可以通过以下几个分类来简化选取过程。
按照IO流的方向:输入流和输出流
I:代表 Input
O:代表 Output
Java 的 IO 流是单向的,只能从输入流(Input、Reader)中读取(read)数据,也只能往输出流(OutputStream、Writer)中写(write/print)出数据
按照IO流的处理数据的基本单位分:
字节流(XxxStream): 直接处理二进制,一个字节一个字节处理,它适用于一切数据,包括纯文本、doc、xls、图片、音频、视频等
字符流(XxxReader 和 XxxWriter): 一个字符一个字符处理,只能处理纯文本类的数据
按照角色分:节点流、处理流
节点流:连接源头、目的地,即被装饰者 IO流
处理流:增强功能,提供性能,即装饰者 IO 流
节点流处于IO操作的第一线,所有操作必须通过他们进行;处理流是通过包装节点流来完成功能的,处理流可以增加很多层。
处理流必须依赖和包装节点流,而不能单独存在。
六、IO 流体系
文件IO流 |
从文件读取 |
FileInputStream |
FileReader |
||
写入到文件 |
FileOutputStream |
|
FileWriter |
||
缓冲IO流 |
从其他输入流中读取
|
BufferedInputStream |
BufferedReader |
||
写入到其他输出流中 |
BufferedOutputStream |
|
BufferedWriter |
||
转换流 |
从其他输入流读取,并解码 |
InputStreamReader |
写入到其他输出流中,并编码 |
OutputStreamWriter |
|
数据流 |
以与机器无关方式从底层输入流中读取基本 Java 数据类型 |
DataInputStream |
以适当方式将基本 Java 数据类型写入输出流中 |
DataOutputStream |
|
对象流 |
序列化 |
ObjectOutputStream |
反序列化 |
ObjectInputStream |
|
打印流 |
|
PrintStream |
|
PrintWriter |
|
其他 |
...... |
|
七、小结