自学Java的第43天:总结下各种IO流

今天是我自学Java的第43天。

感谢你的观看,谢谢你。

话不多说,开始今天的学习:
自学Java的第43天:总结下各种IO流
前两天学习了两种非常基础的IO流:字节流和字符流;

今天我们要继续学习一些更强大的流:

比如能够高效读写的缓冲流;能够转换编码的转换流;能够持久化存储对象的序列化流……等等。

不要一看流那么多,感觉很难记,其实真心不难,无论多少流,核心都是两类:

InputStream字节输入流,核心方法read(),读硬盘数据输入到内存,对应字符输入流Reader;

OutputStream字节输出流,核心方法writer(),写内存数据输出到硬盘,对应字符输出流Writer。
自学Java的第43天:总结下各种IO流
所有的流都是以这两种为核心,都是由字节输出流和字节输入流演化而来,正所谓万流归宗就是这个道理。

使用方法都是大同小异的,只不过前缀不一样。

一、缓冲流

Buffered,翻译为缓冲的,所以缓冲流前缀为Buffered。

它也叫高效流,顾名思义,其使用起来效率很高,经常会使用到它。

它为什么更高效?

因为用空间换时间:底层有一个8K缓冲区专门来做这件事,从而缩短时间,更加地高效。

拿一个我们现实里的例子:电脑卡顿,我们将内存增加,可以在一定程度上解决这个问题。

因为同样是一个程序,以前内存小,只能用100M内存处理这个程序;现在内存大了,专门用200M内存来处理,所以更快了。

这就是用空间换时间

1.字节缓冲流

自学Java的第43天:总结下各种IO流
①构造方法

字节缓冲流,它是在字节流的基础上创建的,所以其参数就是字节流。

其中它还有一个构造方法,额外有一个参数size,可以设定缓冲区的大小,但一般很少使用,都会使用其默认的8K缓冲区。

②复制文件

无论是什么流,它复制文件方法都是大同小异的,无外乎就是read方法,和writer方法,再加上while循环。

③关流

字节缓冲流关闭了,其字节流也会跟着关闭,所以上述虽然创建了4个流,但是只用关闭缓冲流。

2.字符缓冲流

自学Java的第43天:总结下各种IO流

①字符缓冲输出流

和字节缓冲流一样,它也是在字符流的基础上创建的,所以其构造方法参数就是字符流。

其中有一个特有的方法叫newline(),也就是换行;

和写入换行符System.lineSepatator()作用一样。

②字符缓冲输入流

构造方法一样,不做阐述。

其中有一个特有方法readLine(),作用是一次可以读一行。

二、转换流

昨天学习过编码表,编码表就可以理解成翻译,可以将字节翻译成字符。

编码表有很多种,就好比翻译也会有中文翻译,英文翻译,日文翻译一样。

所以编码表不一致的话就会出现乱码。

转换流,便是字节与字符之间的转换的桥梁,它能够指定编码表,防止出现乱码。

自学Java的第43天:总结下各种IO流

①转换输入流

InputStreamReader,它是Reader的子类。

这个名称就特有意思,InputStream字节流,Reader字符流。

所以转换流本质上就是从字节流而来的字符流,在其构造方法中可以指定编码表。

②转换输出流

OutputStreamReader,和输入流是一样的,大同小异。

转换流一般什么时候使用呢?

比如说,我本来一直都是用UTF-8编码表,这有一个特殊需求,有一个特殊文件就是要用GBK编码表。

这种时候就可以用到转换流,但使用不常见。

三、序列化流和反序列化流

前面学了这么多的流,本质上都在操作字节,字符。

现有一个问题:如何将一个自定义对象(比如说学生对象)存储到文件中, 并读取出来?

序列化流就是用来解决这个问题的,

  • 序列化 :将数据结构或对象转换成二进制串的过程,也就是写入文件(输出流)。
  • 反序列化 :二进制串转换成数据结构或对象的过程,也就是读取文件(输入流)。

序列化流和反序列化流的前缀为Object,Object代表着所有对象。

1.使用前提

自学Java的第43天:总结下各种IO流

①实现Serializable接口

Serializable,序列化的意思,它是Java里的一个接口。

若想要将自定义对象存储到文件中,该对象对应的类必须要实现该接口。

②transient关键字

transient,瞬态的意思。

该类的所有属性必须是可序列化的,如果有一个属性不需要可序列化的,则该属性必须使用transient 关键字修饰,注明是瞬态的。

③序列版本号

Serializable 接口给需要序列化的类,提供了一个序列版本号,其目的在于验证序列化的对象和对应类是否版本匹配。

也就是说,哪怕类中的属性发生了变化,在读取文件时(反序列化),也能根据序列版本号找到对应的对象。

2.序列化流

ObjectOutputStream类,这是一个输出流。

序列化流,将Java对象写出到文件,实现对象的持久存储。

自学Java的第43天:总结下各种IO流

①创建序列化流

创建一个对象,以及一个文件obj.txt。

同时创建一个序列化流。

②写入对象

writeObject()方法,将某个对象写入到obj.txt文件中。

3.反序列化流

ObjectInputStream类,这是一个输入流。

反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

自学Java的第43天:总结下各种IO流

①创建反序列化流

②读取对象

readObject()方法,读取对象,该对象也就是序列化存入的对象。

最后在提一个流:打印流

PrintStream:

自学Java的第43天:总结下各种IO流
①这是最常见的系统打印方式,会在控制台上输出。

②创建打印流

打印流的底层也就是创建了一个FileOutputStream(字节输出流),详情见④,所以字节输出流有的方法它也有。

其中也有println方法,也能输入数据到对应文件里面。

③改变系统打印数据的流向

这个是什么意思呢?

就是说,调用setOut(ps)后,系统打印数据不会在控制台上输出了,而是会打印到打印流ps对应的那个文件里。

总结:

自学Java的第43天:总结下各种IO流