字符流
适合操作文本数据
- 所有字符输入流的父类是:Reader
所有字符输出流的父类是:Writer
文件字符输入流:FileReader
创建方法:
new FileReader(File file)
new FileReader(String path)操作方法:
int read(char[] buffer)
void close()操作过程和FileInputStream类似
文件字符输出流(写入器):FileWriter
创建方法:
new FileWriter(File file)
new FileWriter(String path)
new FileWriter(File file,boolean append)
new FileWriter(String path,boolean append)
主要方法:
void write(char[] buffer,int offset,int length)
void write(String str)
void close()
缓冲流
用于加快读写速度,前提是内存的读写效率要远远高于磁盘的读写效率
原理:
会在内存中开辟一个空间作为缓冲区,在读写之前,先将磁盘数据导入到缓冲区,在读写时直接从缓冲区进行读写,减少了直接从磁盘读写次数,从而提高读写效率。
例如:
1024字节 文件100m 访问磁盘 100 * 1024
1024字节 缓冲区 10m 文件100m 访问磁盘 10次
缓冲字节流
缓冲默认大小是8k
BufferedInputStream
创建方法:
- new BufferedInputStream(InputStream in);
在构造方法中传入普通的流,就可以给该流添加缓冲,不需要修改原有流 - new BufferedInputStream(InputStream in,int size)
size可以调整缓冲区 - 主要方法和InputStream一样
BufferedOutputStream
创建方法:
- new BufferedOutputStream(OutputStream out);
- 主要方法和OutputStream一样
缓冲字符流
BufferedReader
创建方法:
new BufferedReader(Reader reader)
new BufferedReader(Reader reader,int size)
特有方法:
String readLine() 一次读取一行文字
BufferedWriter
创建方法:
new BufferedWriter(Writer writer)
new BufferedWriter(Writer writer,int size)
特有方法:
void write(String str)
void newLine() 添加新行
装饰者模式
- 是GOF23设计模式之一
符合开闭原则,开发过程中对程序的修改关闭,对程序的扩展开放
常用的场景:IO
在不修改原有流代码基础上,给原有的流添加新的功能
如何实现:
- 类分为装饰者和被装饰者
- 装饰者和被装饰者都要实现相同的接口(或继承相同的父类)
- 给装饰者传入一个被装饰者对象
在调用装饰者对象方法时,也会调用被装饰者的方法,在此基础上添加新的功能
对象流
特点:可以读写各种Java数据类型以及自定义类型对象
ObjectOutputStream 对象输出流
创建方法:
new ObjectOutputStream(OutputStream out)
new ObjectOutputStream(new FileOutputStream("xxx"));
new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("xxx")));特有方法:
void writeByte(byte data)
void writeShort(short data)
void writeInt(int data)
void writeLong(long data)
void writeChar(char data)
void writeFloat(float data)
void writeDouble(double data)
void writeBoolean(boolean data)
void writeUTF(String data)
void writeObject(Object data)
ObjectInputStream 对象输入流
创建方法:
new ObjectInputStream(InputStream out)
特有方法:
byte readByte()
short readShort()
int readInt()
long readLong()
char readChar()
float readFloat()
double readDouble()
boolean readBoolean()
String readUTF()
Object readObject()
注意:读取数据时,必须和数据写入顺序一致
EOFException End Of File
序列化和反序列化
序列化,将Java对象转换为字节序列保存到磁盘或网络
- 通过ObjectOutputStream的writeObject(Object obj)实现
- 注意:进行序列化的对象必须实现Serializable接口,否则会出现NotSerializableException异常,对象的所有属性也必须实现该接口。
如果某个属性不想进行序列化,可以添加transient关键字
反序列化,将磁盘或网络中的字节序列转换为Java对象
通过ObjectInputStream的readObject()实现
serialVersionUID是序列化版本编号
- 如果没有版本号,系统会自动添加默认的版本号,如果类的对象序列化后,类的代码进行任何修改,默认的版本号就会改变,进行反序列化时就会出现InvalidClassException。
- 解决方法是:创建固定的版本号
NIO
BIO 传统的IO,Blocking IO ,阻塞式IO
阻塞式IO,当流进行读写操作时,会阻塞当前线程,当前线程必须等读写完成后,才能进行后面的操作。
相当于在银行排队,如果没有排到,就什么都不能做。
NIO Non-Blocking IO , 非阻塞式IO
JDK1.4出现的,借助于多路复用器,可以实现多个用户同时访问同一个资源,效率更高,编程比较复杂。
相当于在银行办业务,可以坐着做自己的事情,需要每隔一段时间,去询问大堂经理是否轮到自己,如果没有再继续完成自己的事情。
java.nio包:
Channel 通道
FileChannel 文件通道
SocketChannel 网络通道
Buffer 缓冲区
ByteBuffer 字节缓冲区
CharBuffer 字符缓冲区
Selector 选择器
使用NIO实现文件的复制:
- 创建文件输入流和文件输出流
- 获得文件输入通道和输出通道
- 创建字节缓冲区
- 通过输入通道,将数据输入到缓冲区
从缓冲区取出数据,通过输出通道写入文件
从缓冲区取数据前,将缓冲区由写模式转换为读模式,flip()
将缓冲区数据写入文件后,要重置缓冲区,rewind()关闭流
作业:
- 完成所有课堂案例
- 使用缓冲字符流读取某个目录下的所有java文件并打印出来
- 使用字节缓冲流、字符缓冲流、NIO三种方式实现文件的复制
Person类包括编号、姓名、年龄、性别属性。
创建多个Person对象,添加到集合中,将集合按年龄排序,
保存到文本文件中,格式如:
1 张三 20 男
2 李四 30 女
3 赵四 24 男
4 周五 40 女在文件中保存一个有多个Person对象的集合,然后从文件中将集合读取出来,进行遍历