IO流(BIO)
概念:流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两个设备间的传输成为流,流的本质是数据传输。
一:流的分类
1:按数据类型,分为字节流和字符流
2:按流向分,分为输入流和输出流
如下图
流分为字节流和字符流,每个类型下又有输入流和输出流。
注:Read是输入流,Write是输出流。读使用输入流,写使用输出流。
二:字节流InputStream/OutputStream
1:FileInputStream/FileOutputStream
文件读写流;直接从硬盘读取固定大小字节,没有缓冲;
2:BufferedInputStream/BufferedOutputStream
1):概念
1:BufferedInputStream和其他InputStream常常放在一起使用:
2:BufferedInputStream是套在某个其他的InputStream外,起着缓存的功能,用来改善里面那个InputStream的性能,它自己不能脱离里面那个单独存在。
3:普通读取流,read()读一个字节访问一次磁盘,或者read(byte b[])方法一次读取多个字节,当读取的文件较大时,也会频繁的对磁盘操作,效率太低。BufferedInputStream会开辟一块内存空间(默认大小8192字节),BufferedInputStream是不会读取数据的,真正读取数据的是InputStream子类如FileInputStream。一次与交互读取8192字节的数据放入缓存中。
4:BufferedInputStream中read()即使一个一个字节读取,速度也很快,因为这时候访问的是内存中的数据。也可以指定读取大小的数据read1(byte[] b, int off, int len)。
2):原理
最初本人以为使用的是代理模式,后来发现InPutStram是抽象类,并非接口。所以可以排除代理模式。
那摸根据这种结构,可以定位要么是桥接模式要么是装饰器模式(这三种模式结构很相似)。
以FileInpuStream为例子,因为被增强的FileInpuStream也有自己的API,并不是只能通过BufferedInputStream才能访问相关API(这是其一)。
在者就是FileInpuStream是能够提供完整读取流功能的,并不是一定要和BufferedInputStream结合才能提供完整的功能,所以可以排除桥接模式。
因此可以确定BufferedInputStream使用的是装饰器模式。
3:ObjectInputStream/ObjectOutputStream
Java IO 提供了 ObjectInputStream 和 ObjectOutputStream 来序列化和反序列对象数据。
当我们需要读取存储的基本数据或对象时,可以创建输入流对应的 ObjectInputStream,进而读取出这些基本数据或对象。如果流是网络套接字流,则可以在另一台主机上或另一个进程中反序列化对象。
注意: 只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能被 ObjectInputStream / ObjectOutputStream 所操作!
注意2:与BufferedInputStream一样都是采用装饰器模式,真正操作文件的还是FileInputStream
代码:
package com.test.io;
import lombok.Data;
import java.io.*;
/**
* 对象序列化与反序列化
*/
public class ObjectIOStreamTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//定义对象输出流write/out,写入文件
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/home/wimg/io.txt"));
Person person = new Person();
person.setAge("30");
person.setName("张三");
person.setSex("男");
oos.writeObject(person);
//定义对象输入流read/in,读取文件中的对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/home/wimg/io.txt"));
Person person2 = (Person) ois.readObject();
System.out.println("反序列化:name="+person2.getName());
}
}
@Data
class Person implements Serializable {
private String name;
private String age;
private String sex;
}
三:字符流Reader/Writer