缓冲流
缓冲流
,
也叫高效流,是对
4
个基本的
FileXxx
流的增强,所以也是
4
个流,按照数据类型分类:
字节缓冲流
:
BufferedInputStream
,
BufferedOutputStream
字符缓冲流
:
BufferedReader
,
BufferedWriter
缓冲流的基本原理:
是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统
IO
次数,从而提高读写的效率。
字节缓冲流
构造方法
public BufferedInputStream(InputStream in)
:创建一个 新的缓冲输入流。
public BufferedOutputStream(OutputStream out)
: 创建一个新的缓冲输出流。
普通流复制时间:37993毫秒
缓冲流复制时间:553毫秒
优化缓冲流复制时间:24毫秒
缓冲流复制时间:553毫秒
优化缓冲流复制时间:24毫秒
字符缓冲流
构造方法
public BufferedReader(Reader in)
:创建一个 新的缓冲输入流。
public BufferedWriter(Writer out)
: 创建一个新的缓冲输出流。
特有方法
BufffferedReader
:
public String readLine()
:
读一行文字。
BufffferedWriter
:
public void newLine()
:
写一行行分隔符
,
由系统属性定义符号。
转换流
字符编码和字符集
字符编码
计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制
数转换之后的结果。按照某种规则,将字符存储到计算机中,称为
编码
。反之,将存储在计算机中的二进制数按照
某种规则解析显示出来,称为
解码
。比如说,按照
A
规则存储,同样按照
A
规则解析,那么就能显示正确的文本
f
符
号。反之,按照
A
规则存储,再按照
B
规则解析,就会导致乱码现象。
字符编码
Character Encoding
:
就是一套自然语言的字符与二进制数之间的对应规则。
字符集
字符集
Charset
:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符
号、数字等
计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符
集有
ASCII
字符集、
GBK
字符集、
Unicode
字符集等。
ASCII
字符集
:
ASCII
(
American Standard Code for Information Interchange
,美国信息交换标准代码)是基于拉丁
字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显
示字符(英文大小写字符、阿拉伯数字和西文符号)。
基本的
ASCII
字符集,使用
7
位(
bits
)表示一个字符,共
128
字符。
ASCII
的扩展字符集使用
8
位(
bits
)
表示一个字符,共
256
字符,方便支持欧洲常用字符。
ISO-8859-1
字符集
:
拉丁码表,别名
Latin-1
,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
ISO-5559-1
使用单字节编码,兼容
ASCII
编码。
GBxxx
字符集
:
GB
就是国标的意思,是为了显示中文而设计的一套字符集。
GB2312
:简体中文码表。一个小于
127
的字符的意义与原来相同。但两个大于
127
的字符连在一起时,
就表示一个汉字,这样大约可以组合了包含
7000
多个简体汉字,此外数学符号、罗马希腊的字母、日文
的假名们都编进去了,连在
ASCII
里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这
就是常说的
"
全角
"
字符,而原来在
127
号以下的那些就叫
"
半角
"
字符了。
GBK
:最常用的中文码表。是在
GB2312
标准基础上的扩展规范,使用了双字节编码方案,共收录了
21003
个汉字,完全兼容
GB2312
标准,同时支持繁体汉字以及日韩汉字等。
GB18030
:最新的中文码表。收录汉字
70244
个,采用多字节编码,每个字可以由
1
个、
2
个或
4
个字节
组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。
Unicode
字符集
:
Unicode
编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国
码。
它最多使用
4
个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,
UTF-8
、
UTF-16
和
UTF-
32
。最为常用的
UTF-8
编码。
UTF-8
编码,可以用来表示
Unicode
标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用
中,优先采用的编码。互联网工程工作小组(
IETF
)要求所有互联网协议都必须支持
UTF-8
编码。所以,
我们开发
Web
应用,也要使用
UTF-8
编码。它使用一至四个字节为每个字符编码,编码规则:
1. 128
个
US-ASCII
字符,只需一个字节编码。
2.
拉丁文等字符,需要二个字节编码。
3.
大部分常用字(含中文),使用三个字节编码。
4.
其他极少使用的
Unicode
辅助字符,使用四字节编码。
由于
IDEA
的设置,都是默认的
UTF
-
8
编码,所以没有任何
问题。但是,当读取
Windows
系统中创建的文本文件时,由于
Windows
系统的默认是
GBK编码,就会出现乱码。
InputStreamReader
类
转换流
java.io.InputStreamReader
,是
Reader
的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定
的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法
InputStreamReader(InputStream in)
:
创建一个使用默认字符集的字符流。
InputStreamReader(InputStream in, String charsetName)
:
创建一个指定字符集的字符流。
OutputStreamWriter
类
转换流
java.io.OutputStreamWriter
,是
Writer
的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符
编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。
构造方法
OutputStreamWriter(OutputStream in)
: 创建一个使用默认字符集的字符流。(
创建流对象
,
默认
UTF8
编码
)
OutputStreamWriter(OutputStream in, String charsetName)
:
创建一个指定字符集的字符流。
序列化
Java
提供了一种对象
序列化
的机制。用一个字节序列可以表示一个对象,该字节序列包含该
对象的数据 、 对象的 类型 和 对象中
的属性
等信息。字节序列写出到文件之后,相当于文件中
持久保存
了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行
反序列化
。
对象的数据
、
对象的类型
和
对象中
存储的数据
信息,都可以用来在内存中创建对象。看图理解序列化
ObjectOutputStream
类
java.io.ObjectOutputStream
类,将
Java
对象的原始数据类型写出到文件
,
实现对象的持久存储。
构造方法
public ObjectOutputStream(OutputStream out)
: 创建一个指定
OutputStream
的
ObjectOutputStream
。
序列化操作
1.一个对象要想序列化,必须满足两个条件
:
该类必须实现
java.io.Serializable
接口,
Serializable
是一个标记接口,不实现此接口的类将不会使任
何状态序列化或反序列化,会抛出
NotSerializableException
。
该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用
transient
关键字修饰。
2.
写出对象方法
public final void writeObject (Object obj)
:
将指定的对象写出
ObjectInputStream
类
ObjectInputStream
反序列化流,将之前使用
ObjectOutputStream
序列化的原始数据恢复为对象。
构造方法
public ObjectInputStream(InputStream in)
: 创建一个指定
InputStream
的
ObjectInputStream
。
反序列化操作
1
如果能找到一个对象的
class
文件,我们可以进行反序列化操作,调用
ObjectInputStream
读取对象的方法:
public final Object readObject ()
:
读取一个对象。
对于
JVM
可以反序列化对象,它必须是能够找到
class
文件的类。如果找不到该类的
class
文件,则抛出一个
ClassNotFoundException
异常。
反序列化操作
2
另外,当
JVM
反序列化对象时,能找到
class
文件,但是
class
文件在序列化对象之后发生了修改,那么反序列化操
作也会失败,抛出一个
InvalidClassException
异常。
发生这个异常的原因如下:
该类的序列版本号与从流中读取的类描述符的版本号不匹配
该类包含未知数据类型
该类没有可访问的无参数构造方法
Serializable
接口给需要序列化的类,提供了一个序列版本号。
serialVersionUID
该版本号的目的在于验证序
列化的对象和对应类是否版本匹配。
打印流
平时我们在控制台打印输出,是调用
print
方法和
println
方法完成的,这两个方法都来自于
java.io.PrintStream
类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。
PrintStream
类
构造方法
public PrintStream(String fileName)
: 使用指定的文件名创建一个新的打印流。
改变打印流向
System.out
就是
PrintStream
类型的,只不过它的流向是系统规定的,打印在控制台上。不过,既然是流对象,
我们就可以玩一个
"
小把戏
"
,改变它的流向。