一、IO 流的概述
我们知道存在硬盘中数据是永久保存的,而在内存中的数据只是临时的,内存中的数据可以存入硬盘中,硬盘中的数据也也可以读入内存中。
我们把这种数据的传输,可以看做一种数据的流动,按照流动的方法,以内存为基准,分为
输入 input:流向内存是输入流,从别的地方(文件、键盘、网络、内存等)读取数据到当前程序中。
输出 output:流出内存是输出流,从程序把数据写/输出到文件、屏幕(控制台)、网络、内存等中。
Java 中 I/O 操作主要是指使用 java.io 包下的内容,进行输入、输出操作。
输入也叫做读取数据,输出也叫做写出数据。
注意:
(1)如果对于 File 对象,输入和输出操作只能针对文件,不能针对目录;
(2)IO操作不仅仅是针对文件,可以从网络中输入和输出。
二、IO流的分类
根据数据的流向分为:输入流和输出流。
-
- 输入流:把数据从其他设备上读取到 内存中的流。
- 输出流:把数据从 内存 中写出到其他设备上的流。
- 输入流:把数据从其他设备上读取到 内存中的流。
根据数据的类型分为:字节流和字符流。
-
- 字节流:以字节(Byte)为单位,读写数据的流。
- 字符流:以字符(char)为单位,读写数据的流。
- 字节流:以字节(Byte)为单位,读写数据的流。
区别:字节流适用于读写任何类型的文件。
字符流只能用于读/写纯文本数据,纯文本主要有(txt,html,xml,properties,yml等),如果都读写纯文本文件,字符流快于字节流。
根据数据流的功能角色不同:节点流和处理流
-
- 节点流:和某个节点关联,如,文件流...等
- 处理流:在节点流的基础上,加其他的处理功能,加装饰功能,如,缓冲流,序列化和反序列化等。
- 节点流:和某个节点关联,如,文件流...等
其实 JDK 中 IO 体系是用到了一个装饰者设计模式。
三、IO 的流向说明图解
四、I/O 流的设计
1、IO流的顶级父类
其实不管有多少种 IO 流,最基本的只有四个。
IO流有四大抽象的父类(超类/基类)
2、设计思想
IO 流泪的设计用了 “装饰者”设计模式,即 IO 流分为两大类,“被修饰” 的组件和 “装饰” 的组件。
例如:以 InputStream 为例
其中 FileInputStream、ByteArrayInputStream 等是 “被装饰” 的组件,依次用来连接和读取“文件”,“内存中的字节数组”等。
而 BufferedInputStream、DataInputStream、ObjectInputStream 等是用来“装饰”的组件,依次是给其他 InputStream 的 IO流提供装饰的辅助功能的,依次可以增加“提高效率的缓冲功能”、“按照Java数据类型读取数据的能力”、“读取并恢复Java对象的能力”等
对于另外的 OutputStream、Reader、Writer 系列的流设计方法也是一样的。
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操作的第一线,所有操作必须通过他们进行;处理流是通过包装节点流来完成功能的,处理流可以增加很多层。
处理流必须依赖和包装节点流,而不能单独存在。
扩展:
装饰模式(Decorator Pattern)也称为包装模式(Wrapper Pattern),其使用一种对客户端透明的方式来动态地扩展对象的功能,它是通过继承扩展功能的替代方案之一。在现实生活中你也有很多装饰者的例子,例如:人需要各种各样的衣着,不管你穿着怎样,但是,对于你个人本质来说是不变的,充其量只是在外面加上了一些装饰,有“保暖的”、“好看的”、“防雨的”....
五、常见IO流
文件IO流 |
从文件读取 |
FileInputStream |
FileReader |
||
写入到文件 |
FileOutputStream |
|
FileWriter |
||
缓冲IO流 |
从其他输入流中读取
|
BufferedInputStream |
BufferedReader |
||
写入到其他输出流中 |
BufferedOutputStream |
|
BufferedWriter |
||
转换流 |
从其他输入流读取,并解码 |
InputStreamReader |
写入到其他输出流中,并编码 |
OutputStreamWriter |
|
数据流 |
以与机器无关方式从底层输入流中读取基本 Java 数据类型 |
DataInputStream |
以适当方式将基本 Java 数据类型写入输出流中 |
DataOutputStream |
|
对象流 |
序列化 |
ObjectOutputStream |
反序列化 |
ObjectInputStream |
|
打印流 |
|
PrintStream |
|
PrintWriter |
|
其他 |
...... |
|