java的拉结归宗_【Java】基础43:万流归宗

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

感谢你的观看,谢谢你。

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

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

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

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

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

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

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

191440211_2_202005270736253_wm

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

一、缓冲流

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

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

它为什么更高效?

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

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

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

这就是用空间换时间。

1.字节缓冲流

191440211_3_20200527073625238_wm

①构造方法

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

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

②复制文件

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

③关流

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

2.字符缓冲流

191440211_4_20200527073625332_wm

①字符缓冲输出流

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

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

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

②字符缓冲输入流

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

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

二、转换流

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

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

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

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

191440211_5_20200527073625425_wm

①转换输入流

InputStreamReader,它是Reader的子类。

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

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

②转换输出流

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

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

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

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

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

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

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

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

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

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

1.使用前提

191440211_6_20200527073625519_wm

①实现Serializable接口

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

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

②transient关键字

transient,瞬态的意思。

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

③序列版本号

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

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

2.序列化流

ObjectOutputStream类,这是一个输出流。

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

191440211_7_20200527073625597_wm

①创建序列化流

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

同时创建一个序列化流。

②写入对象

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

3.反序列化流

ObjectInputStream类,这是一个输入流。

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

191440211_8_20200527073625675_wm

①创建反序列化流

②读取对象

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

最后在提一个流:打印流

PrintStream:

191440211_9_20200527073625753_wm

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

②创建打印流

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

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

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

这个是什么意思呢?

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

总结:

191440211_10_20200527073625847_wm

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值