今天是我自学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对应的那个文件里。
总结:
谢谢你的观看。
如果可以的话,麻烦帮忙点个赞,谢谢你。
领取专属 10元无门槛券
私享最新 技术干货