IO流笔记(下)
第一章 缓冲流
1.1 概述
缓冲流,也叫高效流,是对4个基本的FileXXX
流的增强,所以也是4个流,按照数据类型分类:
- 字节缓冲流:
BufferedInputStream
,BufferedOutputStream
- 字符缓冲流:
BufferedReader
,BufferedWriter
缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。
1.2 字节缓冲流
构造方法
-
public BufferedInputStream(InputStream in)
:创建一个新的缓冲输出流(它有第二个参数int size,来指定缓冲区的大小,可以不设置) -
public BufferedInputStream(OutputStream out)
:创建一个新的缓冲输出流 (它有第二个参数int size,来指定缓冲区的大小,可以不设置)
使用步骤
1.3 字符缓冲流
构造方法
-
public BufferedReader(Reader in)
:创建一个新的缓冲输入流(它有第二个参数int size,来指定缓冲区的大小,可以不设置) -
public BufferedWriter(Writer out)
:创建一个新的缓冲输出流(它有第二个参数int size,来指定缓冲区的大小,可以不设置)
特有的成员方法:
- BufferedWriter:
public void newLine( )
写入一个行分割符。会根据不同的操作系统,获取不同的行分割符 - BufferedReader:
public String readLine
:读一行文字
第二章 转换流
2.1 字符编码和字符集
字符编码
按照某种规则,将字符存储到计算机中,称为**编码
。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码
**。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本符号。反之,按照A规则存储,再按照A规则解析,就会出现乱码现象
-
字符编码
Character Encoding
:就是一套自然语言的字符与二进制之间的对应规则。编码表:生活中文字与计算机中的二进制的对应规则
字符集
-
字符集
Charset
:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字,标点符号,图形符号,数字等
计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然有一套字符编码。常见字符集有ASCII字符集,GBK字符集,Unicode字符集等
2.2 编码引出的问题
在IDEA中,使用FileReader
读取项目中的文本文件。由于IDEA的设置,都是默认UTF-8
编码,所以没有任何问题。但是,当读取windows系统中创建的文本文件时,由于windows系统的默认时GBK
编码就会出现乱码
2.3 InputStreamReader类
转换流InputStreamReader是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台默认的字符集
构造方法
-
InputStreamReader(InputStream in)
:创建一个默认字符集的字符流 -
InputStreamReader(InputStream in,String charSetName)
:创建一个指定字符集的字符流
2.4 OutputStreamWriter类
与上面相反
构造方法
-
OutputStreamWriter(OutputStream out)
:创建一个默认字符集的字符流 -
OutputStreamWriter(OutputStream out,String charSetName)
:创建一个指定字符集的字符流
第三章 序列化
3.1 概述
JAVA提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包括对象数据
,对象的类型
和对象中存储的属性
等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象数据
,对象的类型
和对象中存储的属性
信息,都可以用来在内存中创建对象
3.2 ObjectOutputStream类
ObjectOutputStream类,将JAVA对象的原始数据类型写出到文件,实现对象的永久存储
构造方法
-
public ObjectOutputStream(OutputStream out)
:创建一个指定的字节输出流的序列化类
序列化操作
- 一个对象想要序列化,必须满足两个条件:
- 该类必须实现
java.io.serialiazable
接口,serialiazable
是个标记接口,不实现此接口的类将不会使任何状态序列化和反序列化,会抛出NoSerialiazableExcption
- 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化,则该属性必须注明是瞬态的,使用
transient
关键词修饰(被static修饰的成员变量是不可被序列化的,它的功能和static一样,但是没有static的含义)
3.3 ObjectInputStream类
ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复成对象
构造方法
-
public ObjectInputStream(InputStream in)
:创建一个指定的字节输入流的反序列化流
反序列化操作1
如果能找到一个class的对象文件,我们可以进行反序列化操作,调用ObjectInputStream
读取对象的方法:
-
public final Object readObject()
:读取一个对象
反序列化操作2
另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException
异常。
- 该类的序列版本号与从流中读取的类描述的序列版本号不匹配
- 该类包含未知数据类型
- 该类没有可访问的无参构造方法
Serializable
接口给需要序列化的类,提供了一个序列版本号。serialVersionUID
该版本号的目的在于验证序列化的对象和对应类是否版本匹配
但是这个***必须声明为static , final,long 例如:
(public)static final long serialVersionUID=42L
第四章 打印流
4.1 概述
平时我们在控制台打印输出,是调用print
方法和println
方法完成的,这两个方法都来自于java.io.PrintStream
类,该类方法能够方便打印各种数据类型的值,是一种便捷的输出方式
4.2 PrintStream类
构造方法
-
public PrintStream(String fileName)
:使用指定的文件名创建一个新的打印流
改变打印流向
System.out
是PrintStream
类型的,只不过它的流向是系统规定的,打印在控制台上。但是我们可以用一些方法改变它的流向
- 使用
System.setOut( )
:来设置流向,参数填打印的目的地