什么是IO流?
I表示intput,是数据从硬盘进内存的过程,称之为读
O表示output,是数据从内存到硬盘的过程,称之为写
流是一种抽象概念,数据在设备间的传输称为流,流的本质是数据传输
IO流的分类
IO体系下有字节流和字符流;
字节流分为字节输入流、字节输出流
字符流分为字符输入流、字符输出流
字节流
1、字节流的抽象基类、读写
InputStream:这个抽象类是表示字节输入流的所有类的超类
OutputStream:这个抽象类是表示字节输出流的所有类的超类
子类名特点:子类名称都是以其父类名作为子类名的后缀
字节流读写文件使用字节流的抽象类的子类:FileInputStream和FileOutputStream
2、字节流—注意事项
①创建字节输出流对象
如果文件不存在,就创建;如果文件存在就清空。
②写数据
写出的整数,实际写出的是整数在码表上对应的字母
③释放资源
每次使用完流必须要释放资源
3、字节流写数据如何实现追加写入
创建文件输出流以指定的名称写入文件。如果第二个参数为true ,则字节将写入文件的末尾而不是开头
4、字节流-写文本数据注意事项
①创建字节输出流对象
文件不存在就创建,文件存在就清空;如果不想被清空就加true
②写数据
可以写一个字节,可以写一个字节数组,可以写一个字节数组的一部分
windows实现换行:\r\n
③释放资源
字符流
1、字符流写数据
Writer: 用于写入字符流的抽象父类
FileWriter: 用于写入字符流的常用子类
2、字符流写数据的步骤
创建字符输出流的对象
写出数据
3、字符流写数据注意事项
只有刷新流或关闭流,数据才会写入到文件中
flush()刷新流,之后还可以继续写数据
close()关闭流,释放资源,但是在关闭之前会先写出数据。一旦关闭,就不能再写数据
4、字符流读数据
Reader: 用于读取字符流的抽象父类
FileReader: 用于读取字符流的常用子类
5、字符流读数据的步骤
创建字符输入流对象
调用读数据方法
释放资源
6、字符流读数据注意事项
- 创建对象
文件必须存在
- 释放资源
必须关闭流
缓冲流
缓冲流的作用:可以对原始流进行包装,提高原始流读写数据的性能。
1、字节缓冲流
BufferedOutputStream:字节缓冲输出流
BufferedInputStream:字节缓冲输入流
2、字节缓冲流原理
缓冲流的底层自己封装了一个长度为8KB(8129byte)的字节数组,但是缓冲流不能单独使用,它需要依赖于原始流。
读数据时:先用原始字节输入流一次性读取8KB的数据存入缓冲流内部的数组中,再从8KB的字节数组中读取一个字节或者多个字节
写数据时:先把数据写到缓冲流内部的8BK的数组中,等数组存满了,再通过原始的字节输出流,一次性写到目标文件中去。
3、字符缓冲流
字符缓冲输入流
BufferedReader:从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取
字符缓冲输出流:
BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入
转换流
1.什么是转换流?
- InputStreamReader: 用于将字节输入流转换为字符输入流,父类是Reader
- OutputStreamWriter:用于将字节输出流转换为字符输出流,父类是Writer
注意:
存在将字节流转换成字符流的转换流,因为字符流操作文本更简单;
不存在把字符流转换成字节流的转换流,因为没有必要;
对象操作流(序列化流)
1.对象流的基本特点?
对象操作流可以将对象以字节的形式写到本地文件中,需要时可以再次用对象操作流读到内存中,直接变成对象
2.为什么要使用对象流?
对象的信息保存到磁盘中,如果使用前面所学的知识来实现,会非常的繁琐。使用对象流就非常的方便
1.对象操作流介绍
- 对象操作输出流(对象序列化流):ObjectOutputStream
就是将对象保存到磁盘(本地文件)中,或者在网络中传输对象
- 对象操作输入流(对象反序列化流): ObjectInputStream
把写到本地文件中的对象读到内存中,或者接收网络中传输的对象
2.什么是序列化?
序列化就是将对象转换为字节流,以便存储到特点存储介质(例如磁盘)的过程
3.什么是反序列化?
反序列化就是将字节流,转换为对象的过程
注意事项:
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
1.serialVersionUID
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
- 会出问题,会抛出InvalidClassException异常
- 如果出问题了,如何解决呢?
- 重新序列化
- 给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L;
2.transient
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
IO流异常处理
IO流处理异常有两种方式:
使用try...catch...finally语句来处理。格式如下
try{
//有可能产生异常的代码
}catch(异常类 e){
//处理异常的代码
}finally{
//释放资源的代码
//finally里面的代码有一个特点,不管异常是否发生,finally里面的代码都会执行。
}
使用try-with-resource语句处理,格式如下
try(资源对象1; 资源对象2;){
使用资源的代码
}catch(异常类 e){
处理异常的代码
}
try-with-resource是一种简化的释放资源的操作,它会自动释放资源。
IO流小结
字节流可以操作所有类型的文件;
字符流只能处理文本文件;
缓冲流可以提高效率,但是不能直接操作文件,需要传递字节流
复制文本文件,其实就把文本文件的内容从一个文件中读取出来(数据源),然后写入到另一个文件中(目的地)
文件复制需要定义数组提高效率
每次读写一个字符速度慢,想要提高速度需要自定义数组;