缓冲流(高效流)

1.缓冲字节流

  1. 概念:字节缓冲流(输入、输出):BufferedInputStream(输入)、

BufferedOutputStream(输出)。

  1. 构造方法
  1. public BufferedInputStream(InputStream in):

将参数普通的字节输入流,包装成为缓冲的字节输入流。

  1. public BufferedOutputStream(OutputStream out):

将参数普通的字节输出流,包装成为缓冲的字节输出流。

  1. 复制文件的步骤

10.缓冲流、转换流、序列化流_序列化

10.缓冲流、转换流、序列化流_输出流_02

2.缓冲的字符输入流

缓冲的字符输出流:BufferedWriter。
缓冲的字符输入流:BufferedReader。

  1. 构造方法:
    public BufferedWriter(Writer writer):

将参数普通的字符输出流,包装成为缓冲的字符输出流。
public BufferedReader(Reader reader):

将参数普通的字符输入流,包装成为缓冲的字符输入流。
 

  1. 底层

BufferedWriter底层有一个char[8192]缓冲数组。
FileWriter底层有一个byte[8192]缓冲数组。

  1. 额外的方法:new line();

BufferedWriter只有创建new的时候有一些区别,使用起来和FileWriter基本一样。
但是BufferedWriter额外提供了一个换行的方法,备注:这个方法可以自动适应不一样的操作系统,切换到对应的换行符。

  1. 使用步骤

10.缓冲流、转换流、序列化流_输出流_03

3.缓冲的字符输出流

  1. 构造方法

public BufferedReader(Reader reader):将一个普通的字符输入流,包装成为缓冲的字符输入流。

  1. 底层

BufferedReader底层有一个char[8192]数组
FileReader底层有一个byte[8192]数组

  1. 区别

创建的时候有一点区别,使用起来和FileReader基本一样。

  1. 额外的方法

public String readLine():读取一整行字符串,返回值当中不包含换行符。

  1. 使用步骤:单个字符的方式的读取
  1. 缺点
  1. 使用字符数组的方式读取(只有BufferedReader拥有此方法)
  1. String line:代表一行字符串,line可以为空
  2. 所以我们用循环输入line
  3. 为什么要用line去输入?

因为read line一读就是一整行,所以用来判断是否为空了。

10.缓冲流、转换流、序列化流_序列化_04

4.Practice文字段排序

1. 创建一个缓冲的字符输入流BufferedReader,读取一整行:readLine()
2. 将数字和古文进行拆分:split("\\.")-->String[]
3. 将数字、古文两个部分放在对照关系Map当中,创建:HashMap
4. 读取字符串之后,将两个部分放在Map当中:
    4.1 split[0]是字符串,需要转换成为数字:Integer.parseInt
    4.2 split[1]是字符串,代表后面的中文
    4.3 通过Map的put方法放入<Integer, String>,此时HashMap不保证顺序。

10.缓冲流、转换流、序列化流_序列化_05

10.缓冲流、转换流、序列化流_输出流_06

转换流

1.编码

  1. 概念(字符集、编码(规则)、乱码)

字符集:字符符号和字节数字之间的对照关系表。例如ASCII、Unicode都是对照表。
编码:用几个字节以什么样的方式组合来表示字符集当中的一个文字,这种规则叫做编码。例如GBK、UTF-8都是编码。
乱码:写文件的时候,假设使用GBK编码;但是读文件的时候,使用了UTF-8编码。来回编码规则不一样,导致翻译失败,于是乱码。

  1. 引出来ASCII字符集、GBKXXX字符集、unicode字符集(有图解)

一般常用的中文,在GBK当中2个字节,在UTF-8当中3个字节。实际开发当中,全世界都在使用UTF-8统一编码。

文件夹中的文件本来是GBK编码的,但是IDEA默认使用的是UTF-8编码,因为编码不一样,就可能出现乱码现象。

  1. ISO-8859-1字符集(Java web需要谨记的)

2.乱码

  1. 为什么会出现乱码? (有图解)

你好 -> 查询编码表 ->有了规则 –>字节输出流 -> 文本

如果读入的规则和输出的规则不一样了,那么就会产生乱码。

  1. 怎么解决?引出来转换流

解决乱码问题,需要通过GBK去读取文件,不用默认的UTF-8。

这就需要使用转换流:InputStreamReader

3.转换流

a)      转换流: InputStreamReader

构造方法

  1. public InputStreamReader(InputStream in):将参数字节流,按照默认编码转换成为字符流。
  2. public InputStreamReader(InputStream in, String encoding):第二个参数是指定的编码规则。

InputStreamReader其实就是一个Reader的子类,所以使用起来基本一样。
FileReader只能使用默认编码,无法自己指定编码。InputStreamReader可以自己指定编码。

10.缓冲流、转换流、序列化流_构造方法_07

b)     另一个转换流是:OutputStreamWriter

构造方法:

public OutputStreamWriter(OutputStream out):使用默认的编码将参数字节流转换成为字符流。

public OutputStreamWriter(OutputStream out, String encoding):第二个参数是自定义的指定编码。

10.缓冲流、转换流、序列化流_序列化_08


OutputStreamWriter其实就是一个Writer,使用起来和此前的XxxWriter没有什么区别,但是可以指定编码。

 

4.Practice:GBK-> UTF-8

10.缓冲流、转换流、序列化流_输出流_09

序列化

1.序列化

  1. 概念

10.缓冲流、转换流、序列化流_构造方法_10

  1. 数据:成员变量
  2. 从对象到文件中(对象数据只要离开内存就是序列化)
  3. 反序列化(从外面回到内存),objectputStream
  1. 对象的序列化类:ObjectOutputStream
    构造方法:
    public ObjectOutputStream(OutputStream out):参数是字节流,代表希望将对象的数据写到哪里去。
  2. 常用方法:
    public void writeObject(Object obj):将参数对象的数据写到对应的流当中。
  3. 易发错误:NoSerizableException 异常,代表Person类无法序列化,(查看内部,发现Serializable接口(标识接口),代表着没有它不能运行,就是让你知道可以放心的用,类似合格证的作用),但是也是可以忽略它令不参与序列化,其中有个方法:transient关键字。

10.缓冲流、转换流、序列化流_构造方法_11

 

10.缓冲流、转换流、序列化流_输出流_12

2.反序列化ObjectInputStream

  1. 构造方法
    public ObjectInputStream(InputStream in):参数字节流,代表从哪里读取字节数据。
  2. 读对象的方法

public Object readObject():读取得到一个对象

  1. 为什么用object接收对象,因为无法确定对象,

如果在这个过程中,如果发现对象的类已经不存在了,将会发生ClassNotFoundException

所以需要解决这个异常,

如果接下来想要挨个遍历,需要向下转型,需要再去判断一下(intstanceof)

10.缓冲流、转换流、序列化流_构造方法_13

3.版本问题

  1. 原因

10.缓冲流、转换流、序列化流_序列化_14

  1. 解决办法,我们自己生成序列号,自动生成,需要我们在idea里面设置如下:

Settings -> editor -> code style -> java ->

10.缓冲流、转换流、序列化流_序列化_15

10.缓冲流、转换流、序列化流_输出流_16

  1. 要不要使用这个验证码?业务决定

4.集合的序列化

遍历时,考虑到,向下转型集合的序列化,需要对进行的instensof判断,还要对对象进行判断。

  1. 下图是序列化

10.缓冲流、转换流、序列化流_构造方法_17

  1. 下图是反序列化

10.缓冲流、转换流、序列化流_输出流_18

打印流

1.其他流

System.in   标准的输入流对象
System.out  标准的输出流对象
System.err  错误的输出流对象

2.System.out对象类型就是PrintStream打印流。

  1. 常用方法

public void println(任意类型):打印并且换行。
public void print(任意类型):只打印,不换行。

  1. printSream构造方法

如果不希望使用默认的行为,希望让数据可以自定义打印到哪里去,就可以使用方法:
System.setOut(PrintStream out):参数代表输出语句,将数据输出到哪里去。
public PrintStream(String filename):参数是文件路径名。

10.缓冲流、转换流、序列化流_输出流_19