缓冲流(重)

缓冲流介绍

昨天学习了基本的一些流,作为IO流的入门,今天我们要见识一些更强大的流。比如能够高效读写的缓冲流,能够转
换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都是在基本的流对象基础之上创建
而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。
缓冲流是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次
数,从而提高读写的效率。

image.png

缓冲流继承关系

image.png

字节输出缓冲流BufferedOutputStream

BufferedOutputStream 继承OutputStream,,操作时还是使用OutputStream的write方法。
构造方法:
BufferedOutputStream(OutputStream out) 参数要一个基本的流,最终靠基本的流去操作文件。

image.png

字节输入缓冲流 BufferedInputStream

BufferedInputStream 继承InputStream,操作还是使用InputStream的read方法。
构造方法:
BufferedInputStream(InputStream in) 参数要一个基本的流,靠基本的流去操作文件。
image.png

字符输出缓冲流 BufferedWriter

BufferedWriter 继承了Writer,可以使用父类Writer中的write方法。
构造方法:
BufferedWriter(Writer out) 参数要传入基本流,靠基本流来操作文件。
特有方法:
newline() 换行

image.png

字符输入缓冲流 BufferedReader

BufferedReader 继承了Reader,可以使用父类Reader中的read方法。
构造方法:
BufferedReader(Reader in) 参数要传入基本流,靠基本流来操作文件。
特有方法:
String readLine() 读取一行数据返回,读不到时返回null。
image.png
结论:
•读写一个字节,使用缓冲流,可以明显提高效率。
•读写一个字节数组,基本流和缓冲流差别不大。
•缓冲流读写效率高,尽量使用缓冲流去代替基本流的使用。

小结

字符缓冲流为什么提高了操作数据的性能
字符缓冲流自带8K缓冲区
可以提高原始字符流读写数据的性能
说出字符缓冲流的新增功能
public BufferedReader(Reader r)
多了readLine()按照行读取的功能
public BufferedWriter(Writer w)
多了newLine()换行的功能

转换流

字符集和字符编码的概念

计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集
有ASCII字符集、GBK字符集、Unicode字符集等。
image.png

字符流读不同编码的文件乱码

中文在gbk编码中占2个字节,中文在utf-8编码中占3个字节, IDEA默认使用UTF-8编码。
在IDEA中,使用 FileReader 读取项目中的文本文件。由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何问
题。但是,当读取Windows系统中创建的文本文件时,由于文件默认是GBK编码,就会出现乱码。
image.png

乱码原因

image.png

输入转换流 InputStreamReader

InputStreamReader继承 Reader。
可以使用平台默认编码 或者 指定编码 读取字符。
image.png

输出转换流 OutputStreamWriter

OutputStreamWriter继承 Writer。
可以使用平台默认编码 或者 指定编码 写出字符。
image.png

对象流(序列化流)

对象操作流分为两类
ObjectOutputStream 对象输出流
ObjectInputStream 对象输入流
image.png
目标:对象流使用(了解)
对象操作流API

image.png

对象流细节

使用对象输出流将对象保存到文件时会出现NotSerializableException异常。
解决办法:需要让类实现Serializable接口。

用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类结构,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常。

如何解决InvalidClassException异常?
给对象所属的类加一个 serialVersionUID 属性
例如:private static final long serialVersionUID = 5645742L;

如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
给成员变量加transient关键字,该成员变量就不会被序列化到文件中。

image.png

打印流

打印流介绍

字节打印流: PrintStream
继承自FileOutputStream,write()方法和 FileOutputStream 流一样,可以写出字节或者字节数组。
特有的 println() 和 print() 方法,根据参数写出数据。
字符打印流: PrintWriter
继承自Writer,write()方法和 Writer 流一样,可以写出字符或者字符数组或者字符串。
特有的 println()和 print() 方法,根据参数写出数据。
System.out.println()输出语句中的out对象,其实就是一个PrintStream类的对象。
System类内置了一个PrintStream对象,用于将数据快速打印到控制台。

PrintStream的API

image.png
说明:PrintWriter 和 PrintStream 用法几乎一样。
只不过PrintStream是操作字节,PrintWriter是操作字符。
image.png

属性集合(重)

属性集介绍

Properties 类表示属性集。他是一个特殊的集合,可以结合IO流操作。
Properties实现了Map接口,可以当做Map集合使用。
Properties可以结合流进行数据读写,可以把集合中的数据保存到流中,也可以从流中来加载数据。

image.png

Properties作集合使用

Properties实现了Map接口,可以作为一个双列集合使用。
Properties作为集合的特有方法:
image.png

Properties和IO流结合的方法

image.png
image.png

IO流总结

image.png

IO异常处理

JDK7前的处理方式

之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理,建议使用 try…catch…finally 代码
块,处理异常部分。
image.png
JDK7增加 try-with-resource 语句来处理资源,该语句确保了每个资源在语句结束时关闭。
image.png

装饰模式

装饰模式介绍

装饰设计模式的作用
可以原本的类增强和扩展类的功能
装饰设计模式有3个角色
1.原对象
2.装饰对象
3.共同的接口(抽象父类)
image.png