对象流:

ObjectInputStream/ObjectOutputStream:对象流,用于将对象的属性信息保存到磁盘上,和将磁盘里保存的对象读取到程序上。

示意图:

cd29c7dc38d85272928f2109987116d3.png



对象也不是能直接通过对象流保存到磁盘上的,如果要保存的那个对象没有实现Serializable接口是保存不了的,会抛出异常。

  代码示例:

46ce788ee9c8f8649465df1db154f615.png

c4382d19f8f14065cd056bf024458d56.png


运行结果:

0901cbc009ccf260bdb50a4c8a0ea729.png

 没有实现Serializable接口是会抛NotSerializableException异常的。




实现接口后:

c492a8b5cbfc361cda63b813c7bcae03.png

2b8aa7e6d9bee3a463e94b96ac9b3c0d.png



运行结果:

07cb4f04413e01dc9fc35d25e457d056.png




这个接口的内部什么都没有的,就是一个空接口,但是为什么要实现这么一个接口呢,是因为这相当于一个身份的象征,只有实现了这个接口,java虚拟机看到这个对象有这个“身份标记”才能将它的属性保存到磁盘上去。为什么不实现这个接口就不能保存呢?这是因为有些对象属性信息保存着一些比较重要的数据,如果轻易保存到磁盘上就会有一定的风险,所以没有实现这个接口的所有对象是无法被保存的。

 

除了这个需要实现这个接口外还有一个问题,如果我把对象的某个属性删除了或增加某个属性,那么将这个对象读取出来就会发生异常。

  代码示例:

e03d4bc63145b6f08d5cfde10452a39d.png

fb6274468cf5a8fc714a86510a3b9c05.png


运行结果:

05d53e567a0543a7f44ab0d900627d60.png


会发生这个异常的原因是类的版本号不同,每个类编译时都有自己的版本号,对这个类进行更改了,这个类的版本号就会改变。

 

那么解决这个问题的方法就是:自行设置一个唯一的版本号,这玩意就像构造器一样,你写了虚拟机就不会给你自动加了,所以需要自行设置一个唯一的版本号。

  代码示例:

42b98e3edce54e0d4f7a9125c54d894a.png


版本号的数字可以自己任意设置。只要不超出long类型的容量即可。

设置完版本号后,我们再进行实验一下,把对象的某个属性删除了或增加某个属性,看看是否还会抛出异常。

  代码示例:

92b6907e79bc463ce2caa765262cb0c6.png

62878de6bb68c5457b984a7c45f7b726.png


运行结果:

c2afbf7878d2b4c8ae31f9752b1d0552.png

能够正常运行,不会报错。



如果想要对象的某个属性不被存储到硬盘上的时候,就需要用到transient无需序列化关键字。在保存对象的时候加上这个关键字的属性就不会被保存。

  代码示例:

c69f901dd8862860090735eb01150eb3.png

c152f7633a0c24040d74e622be828517.png


运行结果:

480b255ff1b64a964721b5dfddede431.png


从运行结果可以看出,加上这个关键字的属性值就会为null(基本类型值则会为0),表示没有保存。

 

利用对象流可以一个记忆窗口坐标位置的功能,能让窗口程序每次打开都在上一次关闭的位置。

代码示例:

先写好一个具有四个属性分别用于记录窗口的XYWidthHeight坐标的值。并且在构造器声明四个参数,用于传递窗口的XYWidthHeight坐标值:

e16065f92ddfb3a55c8485781e1cff28.png

1a92447681547b3655631d30bfdb7d97.png

0a07eb18a9706d514ac32c3349b73eae.png


  在对象流中要注意的是对象是无法追加输出的,所以不要追加输出。多个对象则可以一起一次性输出,但是同一个对象则无法输出两次。



基本数据类型流:

 DataInputStream/DataOutputStream:基本数据类型流,用于将基本数据类型的值存储到磁盘中,选择输出的数据类型是多少个字节的,那么输出最少就会占用多少个字节。例如int是占用四个字节,那么在输出的时候占用的也是四个字节,其他类型则以此类推。这个流平时并不常用,一般都是专门处理数据方面的人员才会用得上。

 

代码示例:

f43464c61af40f1034c96fa232824a08.png


运行结果:

55bd60a94f6391cde41b67b7b69ae06c.png





加密解密流:

下面介绍最简单的加密方式,如果想要做复杂的加密方式可以自己编写一个加解密算法,但是在公司开发中除非你是专业人员,不然是不需要自行对程序去做加解密的,这些都是由专业的加解密人员去完成,所以对这方面知道个简单原理就可以了。

先编写两个流,一个加密流,和一个解密流。利用装饰设计模式去编写:

加密流:

  代码示例:

b1aaa50bd71d23c391e8d47a95dc312a.png


解密流:

代码示例:

f7446fcddfdafc690a798a5cddc7fa0c.png



测试类:

代码示例:

cdde22ad138fbd256bd680fb9896de8e.png


加密后的文件内容:

6c9bf24438eedc14215f9c6726c61322.png


解密后读取打印出来的内容:

621e2100469631dc79e8af97473fec36.png