# 学习内容:
>* 字节缓冲流
>* 字符缓冲流
>* 编码表
>* 转换流
>* 序列流
>* 打印流
## 缓冲流
> 为了提高IO流读写效率的对象
缓冲流内置了数组的容器
==流对象使用规则:晚开早关==
## 缓冲流对象
##### 字节缓冲流:
* BufferedInputStream
* BufferedOutputStream
##### 字符缓冲流:
* BufferedReader,
* BufferedWriter
### 字节缓冲流
> 构造方法
BufferedXXXXStream (基本字节流对象)
> 装饰设计模式
在原有功能的基础之上,对其进行包装,强化.
##### 缓冲流与字节流对比
推荐方案:
1.普通字节流,自定义数组拷贝
2.缓冲流+自定义数组拷贝
> 结论:这两宗推荐方案,需要根据拷贝的文件大小,以及自定义数组的长度综合评定.不能说谁效率一定更高.
### 字符缓冲流
> 构造方法
BufferedXXXX (基本字符流对象)
> 特有方法
- readLine()
读取一行字符串.
如果没有数据返回`null `
不会读取都回车换行符,需要自己手动换行
- newLine()
写出回车换行,具有跨平台性.
> Tips:
如果输出流与输入流操作的是同一份文件,需要先保存文件内容再关联输出流.(因为关联输出流的时候会清空文件内容)
## 字符编码
> 编码
字符按照指定规则转换字节
> 解码
字节按照指定规则转换字符
#### 字符集
> 编码表
- ASCII: 所有码表都囊括的了ASCII
- IOS-8859-1:拉丁码表 - 没中文
- GBK:国际标准转换码
- UTF-8:万国码
`开发过程中,必须要保证的编码表的统一,否则会造成中文乱码问题`
## 转换流
> 转换流的作用
- A.可以按照指定的编码表读写数据
- B.可以将字节流转换为字符流,并通过字符流的思想操作数据
`字符流=字节流+默认编码表`
`转换流=字节流+指定编码表`
- `传入一个字节流,也可以传入一个包装过缓冲流的字节流字节流,先转换流后缓冲流包装和先缓冲流包装后转换流.是没有区别的`
## InputStreamReader类
> 构造方法
- InputStreamReader(InputStream in) :
创建一个使用默认字符集的字符流。
- InputStreamReader(InputStream in, String.charsetName) :
创建一个指定字符集的字符流。
> 使用流程
1.创建转换流对象-->传送指定编码表
2.调用读取方法
3.关闭流资源
## OutputStreamWriter类
> 构造方法
- OutputStreamWriter(OutputStream in) :
创建一个使用默认字符集的字符流。
- OutputStreamWriter(OutputStream in,String charsetName) :
创建一个指定字符集的字符流。
## 序列流
> 解释
就是可以将整个对象写出到文件当中,也可以将文件中存储的对象读取出来.
- 序列化:将对象持久化写出
`ObjectOutputStream类`
- 反序列化:将对象从文件读取出来
`ObjectInputStream类`
> 构造方法
- public ObjectOutputStream(OutputStream out) :
创建对象输出流,关联输出流.
- public ObjectInputStream(InputStream in)
读取对象,关联输入流.
> 方法
- writeObject() 写入一个对象
- readObject() 读取一个对象
> 序列化操作
- **一个对象要想序列化,必须满足两个条件:**
1.该类必须实现java.io.Serializable接口,`Serializable`是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出`NotSerializableException` 。
2.该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用
`transient` 关键字修饰。
> 反序列化操作
- 对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个ClassNotFoundException 异常。
- 另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个 InvalidClassException 异常。发生这个异常的原因如下:
1.该类的序列版本号与从流中读取的类描述符的==版本号==不匹配
2.该类包含未知数据类型
3.该类没有可访问的无参数构造方法 `Serializable接口给需要序列化的类,提供了一个序列版本号。serialVersionUID该版本号的目的在于验证序
列化的对象和对应类是否版本匹配。`
### 序列化集合
> 如果要持久存储多个对象,存入集合直接存储List集合.
读取的时候可以确定对象数量,避免EOFException异常.
### 打印流
> 注意事项
- 流操作数据目的,不操作数据源.
`只能输出不能读取`
#### PrintStream
- System.out获取的,就是一个标准输出流,默认指向控制台