IO流笔记(下)

第一章 缓冲流

1.1 概述

缓冲流,也叫高效流,是对4个基本的FileXXX流的增强,所以也是4个流,按照数据类型分类:

  • 字节缓冲流:BufferedInputStreamBufferedOutputStream
  • 字符缓冲流:BufferedReaderBufferedWriter

缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。

1.2 字节缓冲流

构造方法

  • public BufferedInputStream(InputStream in):创建一个新的缓冲输出流(它有第二个参数int size,来指定缓冲区的大小,可以不设置)
  • public BufferedInputStream(OutputStream out):创建一个新的缓冲输出流 (它有第二个参数int size,来指定缓冲区的大小,可以不设置)

使用步骤

IO流笔记(下)

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提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包括对象数据对象的类型对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息

反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象数据对象的类型对象中存储的属性信息,都可以用来在内存中创建对象

IO流笔记(下)

3.2 ObjectOutputStream类

ObjectOutputStream类,将JAVA对象的原始数据类型写出到文件,实现对象的永久存储

构造方法

  • public ObjectOutputStream(OutputStream out):创建一个指定的字节输出流的序列化类

序列化操作

  1. 一个对象想要序列化,必须满足两个条件:
  • 该类必须实现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.outPrintStream类型的,只不过它的流向是系统规定的,打印在控制台上。但是我们可以用一些方法改变它的流向

  • 使用System.setOut( ):来设置流向,参数填打印的目的地