首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

小说里有万剑归宗,Java里也有万流归宗,万流齐发

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

感谢你的观看,谢谢你。

话不多说,开始今天的学习:

前两天学习了两种非常基础的IO流:字节流和字符流。

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

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

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

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

OutputStream字节输出流,核心方法writer(),写内存数据输出到硬盘,对应字符输出流Writer。

所有的流都是以这两种为核心,都是由字节输出流和字节输入流演化而来,正所谓万流归宗就是这个道理。使用方法都是大同小异的,只不过前缀不一样。

一、缓冲流

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

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

它为什么更高效?

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

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

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

这就是用空间换时间

1.字节缓冲流

构造方法

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

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

复制文件

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

关流

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

2.字符缓冲流

字符缓冲输出流

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

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

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

字符缓冲输入流

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

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

二、转换流

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

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

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

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

转换输入流

InputStreamReader,它是Reader的子类。

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

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

转换输出流

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

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

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

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

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

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

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

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

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

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

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

1.使用前提

实现Serializable接口

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

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

transient关键字

transient,瞬态的意思。

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

序列版本号

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

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

2.序列化流

ObjectOutputStream类,这是一个输出流。

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

创建序列化流

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

同时创建一个序列化流。

写入对象

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

3.反序列化流

ObjectInputStream类,这是一个输入流。

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

创建反序列化流

读取对象

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

最后在提一个流:打印流

PrintStream:

这是最常见的系统打印方式,会在控制台上输出。

创建打印流

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

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

改变系统打印数据的流向

这个是什么意思呢?

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

总结:

谢谢你的观看。

如果可以的话,麻烦帮忙点个赞,谢谢你。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200527A0LR3000?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券