缓冲流(重)
缓冲流介绍
昨天学习了基本的一些流,作为IO流的入门,今天我们要见识一些更强大的流。比如能够高效读写的缓冲流,能够转
换编码的转换流,能够持久化存储对象的序列化流等等。这些功能更为强大的流,都是在基本的流对象基础之上创建
而来的,就像穿上铠甲的武士一样,相当于是对基本流对象的一种增强。
缓冲流是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次
数,从而提高读写的效率。
缓冲流继承关系
字节输出缓冲流BufferedOutputStream
BufferedOutputStream 继承OutputStream,,操作时还是使用OutputStream的write方法。
构造方法:
BufferedOutputStream(OutputStream out) 参数要一个基本的流,最终靠基本的流去操作文件。
字节输入缓冲流 BufferedInputStream
BufferedInputStream 继承InputStream,操作还是使用InputStream的read方法。
构造方法:
BufferedInputStream(InputStream in) 参数要一个基本的流,靠基本的流去操作文件。
字符输出缓冲流 BufferedWriter
BufferedWriter 继承了Writer,可以使用父类Writer中的write方法。
构造方法:
BufferedWriter(Writer out) 参数要传入基本流,靠基本流来操作文件。
特有方法:
newline() 换行
字符输入缓冲流 BufferedReader
BufferedReader 继承了Reader,可以使用父类Reader中的read方法。
构造方法:
BufferedReader(Reader in) 参数要传入基本流,靠基本流来操作文件。
特有方法:
String readLine() 读取一行数据返回,读不到时返回null。
结论:
•读写一个字节,使用缓冲流,可以明显提高效率。
•读写一个字节数组,基本流和缓冲流差别不大。
•缓冲流读写效率高,尽量使用缓冲流去代替基本流的使用。
小结
字符缓冲流为什么提高了操作数据的性能
字符缓冲流自带8K缓冲区
可以提高原始字符流读写数据的性能
说出字符缓冲流的新增功能
public BufferedReader(Reader r)
多了readLine()按照行读取的功能
public BufferedWriter(Writer w)
多了newLine()换行的功能
转换流
字符集和字符编码的概念
计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集
有ASCII字符集、GBK字符集、Unicode字符集等。
字符流读不同编码的文件乱码
中文在gbk编码中占2个字节,中文在utf-8编码中占3个字节, IDEA默认使用UTF-8编码。
在IDEA中,使用 FileReader 读取项目中的文本文件。由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何问
题。但是,当读取Windows系统中创建的文本文件时,由于文件默认是GBK编码,就会出现乱码。
乱码原因
输入转换流 InputStreamReader
InputStreamReader继承 Reader。
可以使用平台默认编码 或者 指定编码 读取字符。
输出转换流 OutputStreamWriter
OutputStreamWriter继承 Writer。
可以使用平台默认编码 或者 指定编码 写出字符。
对象流(序列化流)
对象操作流分为两类
ObjectOutputStream 对象输出流
ObjectInputStream 对象输入流
目标:对象流使用(了解)
对象操作流API
对象流细节
使用对象输出流将对象保存到文件时会出现NotSerializableException异常。
解决办法:需要让类实现Serializable接口。
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类结构,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常。
如何解决InvalidClassException异常?
给对象所属的类加一个 serialVersionUID 属性
例如:private static final long serialVersionUID = 5645742L;
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
给成员变量加transient关键字,该成员变量就不会被序列化到文件中。
打印流
打印流介绍
字节打印流: PrintStream
继承自FileOutputStream,write()方法和 FileOutputStream 流一样,可以写出字节或者字节数组。
特有的 println() 和 print() 方法,根据参数写出数据。
字符打印流: PrintWriter
继承自Writer,write()方法和 Writer 流一样,可以写出字符或者字符数组或者字符串。
特有的 println()和 print() 方法,根据参数写出数据。
System.out.println()输出语句中的out对象,其实就是一个PrintStream类的对象。
System类内置了一个PrintStream对象,用于将数据快速打印到控制台。
PrintStream的API
说明:PrintWriter 和 PrintStream 用法几乎一样。
只不过PrintStream是操作字节,PrintWriter是操作字符。
属性集合(重)
属性集介绍
Properties 类表示属性集。他是一个特殊的集合,可以结合IO流操作。
Properties实现了Map接口,可以当做Map集合使用。
Properties可以结合流进行数据读写,可以把集合中的数据保存到流中,也可以从流中来加载数据。
Properties作集合使用
Properties实现了Map接口,可以作为一个双列集合使用。
Properties作为集合的特有方法:
Properties和IO流结合的方法
IO流总结
IO异常处理
JDK7前的处理方式
之前的入门练习,我们一直把异常抛出,而实际开发中并不能这样处理,建议使用 try…catch…finally 代码
块,处理异常部分。
JDK7增加 try-with-resource 语句来处理资源,该语句确保了每个资源在语句结束时关闭。
装饰模式
装饰模式介绍
装饰设计模式的作用
可以原本的类增强和扩展类的功能
装饰设计模式有3个角色
1.原对象
2.装饰对象
3.共同的接口(抽象父类)