1.1 什么是IO
所谓IO即input和output的缩写,是对数据的流入和流出的一种抽象,编程中很常见的一个概念。
1.2 什么是流
流是指在计算机的输入输出设备之间运动的数据序列。数据序列看着是二进制数据
1.3 java io
java为了我们调用方便,而屏蔽输入/输出源和流动细节,抽象出的用于解决数据流动问题的类体系,这就是java的io流
1.4 输入流和输出流
用于读取的流称为输入流(输入流只能用来读),用于写入的流称为输出流(输出流只能用来写)。输入输出的概念一般是针对内存来说的,流(写)入内存,从内存流(读)出。
1.5 字节流和字符流
输入输出流可操作最小单位来区分字节流和字符流,最小操作单位是一个字节(8bit)的为字节流,最小操作单位为一个字符(16bit)的为字符流,java io体系中字节操作流以stream结尾,字符操作流以reader和writer结尾
1.6 节点流和包装(处理)流
1)节点流偏向实现细节,直接与细节打交道,比如FileInputStream,而包装(处理)流偏功能,以目标功能为抽象,比如PrintStream。
2)区分节点流和包装(处理)流最简单的一个方式:处理流的构造方法中需要另一个流作为参数,而节点流构造方法则是具体的物理节点,如上FileInputStream构造法中需要一个文件路径或者File对象,而PrintStream构造方法中则需要一个流对象
3)包装流使用了装饰器模式(什么是装饰器模式?传送门),包装流对节点流进行了一系列功能的强化包装,让包装后的流拥有了更多的操作手段或更高的操作效率,而隐藏节点流底层的复杂性。
1.7 低级流和高级流
低级流和高级流对应的概念即对应上面的节点流和包装(处理)流概念
1.8 普通流和缓冲流
普通流和缓冲流主要是针对读写性能上提出的相对概念。普通流与缓冲流的区别在于一个一个数据的流动还是一堆一堆数据的流动。
下面列出read和write的方法原型(这里以字节流为例,字符流道理相同):
stream的read
int read();//返回值代表当前读取的字节(8bit)所对应的整形
int read(byte b[]);//将读入的数据装入缓冲区b,实际装了几个字节?实际装了返回值大小个字节,最常使用的read方法
int read(byte b[], int off, int len);//将读入的数据装入缓冲区b,从哪开始装?从off开始,装几个字节?装len个,实际装了几个?实际装了返回值大小个字节
stream的write
void write(int b);//一次写入一个字节,写入的内容是整型b所对应的二进制数据写入流中
void write(byte b[]);//一次将b数组中的数据写入流中
write(byte b[], int off, int len);//将b数组中区间为[off,off+len]的数据写入流中,最常使用的write方法
int read();//返回值代表当前读取的字节(8bit)所对应的整形
int read(byte b[]);//将读入的数据装入缓冲区b,实际装了几个字节?实际装了返回值大小个字节,最常使用的read方法
int read(byte b[], int off, int len);//将读入的数据装入缓冲区b,从哪开始装?从off开始,装几个字节?装len个,实际装了几个?实际装了返回值大小个字节
// stream的write
void write(int b);//一次写入一个字节,写入的内容是整型b所对应的二进制数据写入流中
void write(byte b[]);//一次将b数组中的数据写入流中
如果不考虑性能会有如下两种形式来读写:读入一个字节,写入一个字节;使用缓冲区读入一堆字节,然后将缓冲区数据进行写入输出流。如下:
//读一个字节,写一个字节
int b = 0;
while((b = fis.read()) != -1){
fos.write(b);
}
//读入一堆,写入一堆
int b = 0;
byte[] buff = new byte[size];
while((b = fis.read(buff)) != -1){
fos.write(buff,0,b);//将缓冲数组索引区间为[0,b]的数据写入
}