*1、对象操作流
2、打印流
3、【Properties】
4、【IO中标准的关流格式】
*
一、对象操作流
(一)概述
1、用于将内存中的对象,直接写入到文件中,或者从文件中读取对象到内存
2、对象输出流:ObjectOutputStream
3、对象输入流:ObjectInputStream
(二)对象输出流
1、ObjectOutputStream:也是一个字节输出流,是OutputStream的子类,可以输出一个对象,用于将内存中的对象,输出到其他设备中,例如:文件、网络等
2、ObjectOutputStream是一个包装类,可以将一个没有输出对象功能的字节输出流,包装成具有输出对象功能的流,包装完成之后,可以使用更多的方法
3、构造方法:ObjectOutputStream(OutputStream out) 将一个普通的字节输出流对象包装成对象输出流
4、成员方法:writeObject(Object obj) 将内存中的obj对象,输出到其它设备
5、注意事项:
(1)要存储到文件中的对象,其所属类型必须实现Serializable接口
(2)对象存储到文件的时候,不存在编码操作,也不存在解码操作,仅仅是将内存中对象的字节信息,搬运到文件中而已。我们使用文本编辑器代开存有对象字节信息的文件时,会按照字符集对字节信息解码,但是当前的字节信息表示的是Java对象,并不是字符,所以一定会乱码。因为这个文件仅仅是一个用于存储字节信息的容器,本部应该用文本编辑器打开,也不适用于给人类阅读的,而是将来用于对象输入流去操作的。
(三)对象输入流
1、ObjectInputStream:也是一个字节输入流,不具有读写功能,是一个包装类,将其他的字节输入流包装成一个对象输入流
2、作用:是InputStream子类,将文件中、网络中的对象,读取到内存中,进行使用
3、构造方法:ObjectInputStream(InputStream in) 将其他的字节输入流包装成一个对象输入流
4、成员方法:readObject() 将其它设备中的对象,读取进内存
(四)文件末尾异常
1、当我们使用对象输入流读取存储对象字节信息的文件时,如果已经读取完毕整个文件,还要去读取,就会出现异常:EOFException
2、EOFException:End of File Exception 文件末尾异常
3、避免方式:在写出对象到文件的时候,不要直接将对象写出到文件;应当先将这些对象存储到一个集合中,将集合整体写出到文件中(实际上就相当于只将一个对象——集合对象输出到了文件);将来读取的时候,主需要读取到一个集合对象,只有遍历集合对象,就能得到所有的对象。
(五)【序列化和反序列化】
1、概念解释:
(1)序列化:对象从内存到其它设备的过程
(2)反序列化:对象从其它设备到内存的过程
2、序列化和反序列化,都需要实现接口:java.io.Serializable
3、如果要将一个类的对象进序列化或者反序列化操作,没有实现java.io.Serializable接口,就会出现:
NotSerializableException
(六)【版本号问题】
1、含义:修改了本地的Person类型,新的类型和文件中对象所属的类型已经不一致了,所以两个版本的Person类型冲突了,标志就是两个版本的序列化版本id不同
2、解决:不要直接将类的对象输出到文件中进行序列化,在序列化之前应当对类添加版本号(序列化ID),添加了序列化ID之后,就算类再怎么变,将来一样能够对文件中的对象进行反序列化
二、打印流
(一)概述
1、打印流:
(1)打印字节流:PrintStream
(2)打印字符流:PrintWriter
2、特点:提供了很多的print和println方法,可以很方便的输出各种数据类型的数据,包括基本数据类型和JDK提供的引用数据类型以及自定义类型的数据
3、说明:不论是PrintStream还是PrintWriter,实际上他们的print方法,都各自依赖他们的父类中的write方法,他们的println方法,实际上又都是在依赖他们的print方法
(二)PrintStream
1、打印字节流:System.out就是这个流的对象
2、在该类型中,提供了很多print和println方法的重载,可以将各种数据类型的数据进行输出打印
3、注意事项:
(1)如果使用System.out获取到的PrintStream对象,是默认关联到显示器控制台的,但是如果使用构造方法创建的PrintStream类型的对象,需要我们指定关联的位置
(2)PrintStream中重载了很多print和println方法,其中println方法还是借助print方法进行输出,只是比print方法多了一个换行操作而已
(3)在诸多的print方法重载中,所有的数组都会走print(Object obj)方法,直接将数组地址转为字符串并且打印,只有一个方法print(char[] arr)为char[]数组专门提供了一个参数,底层是对char数组进行遍历,并不是打印地址值,所以当我们用输出语句输出char数组名称时,看到的是数组内容,不是数组地址
4、构造方法:
(1)PrintStream(String fileName) 创建打印字节流对象,打印的位置由参数指定
(2)PrintStream(File file) 创建打印字节流对象,打印的位置由参数指定
(3)PrintStream(OutputStream out, boolean autoFlush) 将一个字节流包装成打印流,如果参
数而填写true,就会开启自动刷新,需要配合println方法才能实现自动刷新
(三)PrintWriter
1、打印字符流,其中和PrintStream一样,都有很多的print和println方法,其中参数也基本相同,功能也基本相同
2、PrintWriter是一个字符输出流,是Writer的子类,有一个缓冲区,就涉及到刷新功能
3、PrintWriter提供了自动刷新:PrintWriter(OutputStream out, boolean autoFlush) 或者
PrintWriter(Writer out, boolean autoFlush) 将字节输出流对象(字符输出流对象)包装成一个打印字符流,并且能够开启自动刷新
4、使用自动刷新的方式:
(1)通过3中的构造方法将一个字节输出流(字符输出流)包装成打印字符流对象,并且将自动刷新置为true,开启自动刷新
(2)如果要使用自动刷新,只能配合println、printf或者format方法进行操作,其他的方法自动刷新不起效,因为自动刷新的标志是要看到’\n’的
三、Properties
(一)概述
1、Properties类是Hashtable的子类,也是一个双列集合,拥有键值对的特性
2、Properties类表示一个持久的属性集
(1)属性集:属性名和属性值的对应关系,并且是一个双列集合
(2)持久的:可以通过流写出到配置文件上,存储在磁盘中进行持久化,也可以通过流将配置文件中
的属性集读取出来
3、Properties类型没有泛型,是因为配置文件中的信息,读取到Properties类对象后,都是以字符串的
形式表示的,所以Properties类型不需要使用泛型,来表示广泛的类型,键值对本身都会是一个字符串
4、Properties既然作为Hashtable的子类,当然也具有双列集合应有的特性
(二)Properties中特有的方法
1、setProperty(String key, String value) 向Properties中添加String类型的键值对,实际上在调用
Hashtable的put方法(键不存在就添加键值对,如果键存在就根据键修改值)
2、getProperty(String key) 根据键获取值
3、stringPropertyNames() 获取当前Properties对象中的键集(Set集合)
(三)Properties加载配置文件
1、load(InputStream inStream) 通过参数传入一个字节输入流来读取配置文件,将配置文件中的内容
加载到Properties对象中
2、load(Reader reader) 通过参数传入一个字符输入流来读取配置文件,将配置文件中的内容加载到
Properties对象中
3、store(OutputStream out, String comments) 通过参数传入一个字节输出流来将Properties对象
中将修改后的键值对信息输出到配置文件中,并且将添加的String注释也写出到配置文件中
4、store(Writer writer, String comments) 通过参数传入一个字符输出流来将Properties对象中将修改
后的键值对信息输出到配置文件中,并且将添加的String注释也写出到配置文件中
四、IO中标准的关流格式
(一)JDK7之前
1、将流对象的创建和流对象的关闭分离开,分别放在try和finally中,即便是创建流对象失败,也能够保证关流操作可以执行
2、为了try和finally中的都可以使用流对象的引用,将流对象的声明放在最外层,保证到处能够访问
3、为了保证两个引用有初始化值,不会违背变量在方法中先赋值后使用的原则,所以赋值为null
4、为了避免两个流对象中,其中一个关流失败后另一个无法关闭的情况,使用try…catch…finally嵌套
5、为了避免对象创建失败就去关流造成空指针异常,在关流前先判断对象是否存在
(二)JDK7之后
1、格式:
try(
需要关闭资源的对象
) {
流对象的使用
} catch…
2、说明:流对象使用之后,不需要手动关闭,这个格式可以帮我们自动关闭流对象