IO流
程序的运行在内存中执行,程序结束时,数据丢失,为了让数据永久保存,需要外部存储器完成
我们可以使用输入输出(I/O)完成内存和外存之间的数据传输
按方向分
- 输入流 数据从数据源读取到内存是输入流也叫读取流
- 输出流 数据从内存写入到数据源是输出流也加写入流
按传输内容分
- 字节流 传输二进制字节数据
- 字符流 传输字符数据
- 对象流 传输对象数据
无论传输的是什么数据,在底层都是以字节方式传输,所以真正的流只有一种就是字节流,为了方便开发者对字符数据和对象数据进行操作,javaAPI对字节流进行了一层封装,形成了字符流和字节流
字节流的抽象父类
- InputStream
- OutputStream
字符流的抽象父类
- Reader
- Writer
流的子类
不同的数据源写数据的方式会有所不同,所以在字节流和字符流的父类中,预留了读写数据的抽象方法,不同的子类根据自己数据源的特点分别去实现
- BufferedInputStream 数据源是缓冲区
- FileInputStream 数据源是文件
- ObjectInputStream 数据源是对象
流操作的步骤
- 创建流
- 操作流
- 关闭流
注意操作文件流时,如果文件不存在,对于读取流会抛出文件未找到异常,对于写入流会创建新文件(目录必须存在)
流操作完成后需要完成流的关闭,否则不仅浪费内存资源,写入流还有可能不能写进去数据
写入流写入操作时,需要通过flush()刷新语句,才能真正的将数据写入数据源。在流关闭时,会自动执行flush()刷新语句,所以写入流在不关闭,也不刷新的情况下,有可能写不进数据
对象序列化
在传输对象时,由于对象的数据庞大,无法直接传输,所以在传输之前,先把对象打散成字节序列,以利于传输,这个过程称为对象序列化
在字节序列到达目的地后,又需要将字节序列还原成对象,这个过程称为反序列化过程
但是不是任何对象都能被打散成字节序列,在java中所有需要实现序列化的对象,必须首先实现java.io.Serializable接口
如果未实现接口会抛出NotSerializableException异常