IO相关知识(Filter/序列化)

1.Filter模式

a.简介

        i.直接使用继承,为各种InputStream附加更多功能,根本无法控制代码的复杂度,很快就会失控。
        ii.为了解决依赖继承会导致子类数量失控的问题,JDK首先将InputStream分为两大类:
                1.提供数据的基础的InputStream
                        a.FileInputStream:文件
                        b.ByteArrayInputStream:数组
                        c.ServletInputStream:网络
                2.提供额外附加功能的InputStream
                        a.BufferedInputStream:缓冲
                        b.DigestInputStream:计算签名
                        c.CipherInputStream:加/解密
        iii.通过一个“基础”组件再叠加各种“附加”功能组件的模式,称为Filter模式(或者装饰器模式:Decorator)。 它可以通过少量的类来实现各种功能的组合。

b.编写FilterInputStream

        i.可以把自己的FilterInputStream叠加到任何一个InputStream中。
        ii.叠加多个FilterInputStream,我们只需要持有最外层的InputStream。try(resource)语法,外层内层的InputStream的close()方法都会调用,所有资源都会关闭,因此不存在资源泄露。
        iii.编写一个CountInputStream,对输入的字节进行计数。

c.总结

        i.Java的IO标准库使用Filter模式为InputStream和OutputStream增加功能:
                1.可以把一个InputStream和任意个FilterInputStream组合。
                2.可以把一个OutputStream和任意个FilterOutputStream组合。
        ii.Filter模式可以在运行期动态增加功能(又称Decoartor模式)。

2.序列化

a.简介

        i.序列化是把一个Java对象变成二进制内容(byte[]数组);反序列化是把一个二进制内容(byte[]数组)变回Java对象。
        ii.Java对象序列化后可以把byte[]保存到文件中,或把byte[]通过网络传输到远程。
        iii.Java对象序列化,需实现java.io.Serializable接口。
        iv.Serializable没有定义任何方法,是一个空接口,称为“标记接口”(Marker Interface),实现了标记接口的类仅仅是给自身贴了个“标记”,没有增加任何方法。

b.序列化

        i.把一个Java对象变为byte[]数组,需要使用ObjectOutputStream。它负责把一个Java对象写入一个字节流。ObjectOutputStream可以写入基本类型,String,实现了Serializable接口的Object。

c.反序列化

        i.ObjectInputStream负责从一个字节流读取Java对象。可以读基本类型和String,调用readObject()可以直接返回一个Object对象,要把它变成特定类型,必须强制转型。

        ii.readObject()可能抛出的异常
                1.ClassNotFoundException:没有对应的Class。即序列化时传的Person对象,在反序列化程序中没有。
                2.InvalidClassException:Class不匹配。即序列化时Person类的age定义的是int,反序列化时Person类的age定义的是long,导致class不兼容。
        iii.为避免这种class定义导致的不兼容,Java的序列化允许class定义一个特殊的serialVersionUID静态变量。
        iv.反序列化时,由JVM直接构造出Java对象,不调用构造方法,构造方法内部的代码,在反序列化时根本不执行。

d.安全性

        i.Java的序列化机制可以导致实例直接通过byte[]数组创建,不调用构造方法。byte[]数组被反序列化后可执行特定的代码,存在安全隐患。
        ii.Java的序列化和反序列化机制即存在安全性问题,又存在兼容性问题。更好的序列化方法是通过JSON这样的通用数据结构来实现,只输出基本类型(包括String)的内容,不存储任何代码信息。
        iii.序列化机制仅适应于Java,需要与其他语言交换数据,必须使用通用的序列化方法,例如JSON。

3.操作Zip

a.简介

        i.ZipInputStream是一种FilterInputStream。
        ii.ZipOutputStream是一种FilterOutputStream。

b.读取zip包

        i.FileInputStream作为数据源,循环调用getNextEntry(),返回null,表示zip流结束。
        ii.一个ZipEntry表示一个压缩文件或目录,如果是压缩文件,就用read()方法不断读取,返回-1表示结束。

c.写入zip包

i.ZipOutputStream可以直接写入内容到zip包,包装一个FileOutputStream,写入每个文件前,先调用putNextEntey(),然后用write()写入byte[]数据,最后调用closeEntry()结束这个文件的打包。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值