概述
Java的核心库java.io提供了全面的IO接口。包括:文件读写、标准设备输出等。Java中IO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。
IO是指对数据流的输入和输出,也称为IO流,IO流主要分为两大类,字节流和字符流。字节流可以处理任何类型的数据,如图片,视频等,字符流只能处理字符类型的数据。
相关类或接口
InputStream -- 字节输入流(接口)
OutputStream -- 字节输出流(接口)
Reader -- 字符输入流(接口)
Writer -- 字符输出流(接口)
File -- 文件类
RandomAccessFile -- 随机存储文件类
设计模式之装饰者模式
先看一段代码:
DataOutputStream outputStream = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(file)));
被这么多嵌套给绕晕了。。。java io就是装饰者模式的典型,接下来我将围绕着装饰模式来展开IO相关类的学习。

装饰模式中的角色:
抽象构件(Component)角色:Component是一个抽象类或接口,是要包装的原始对象。
具体构件(ConcreteComponent)角色:是Component的实现类,最终要装饰的实际对象。
装饰(Decorator)角色:是一个抽象类,继承或实现了Component的接口,同时它持有一个对Component实例对象的引用,也可以有自己的方法。
具体装饰(ConcreteDecorator)角色:是Decorator的实现类,是具体的装饰者对象,负责给ConcreteComponent附加责任。
java流类图结构

转载自:https://www.cnblogs.com/oubo/archive/2012/01/06/2394638.html
装饰模式之InputStream(字节流)
从IO中输入字节流的继承图中可以看出。
1)InputStream是所有数据字节流的父类。
是个接口,也是上面提到的抽象构件(Component)角色。
2)ByteArrayInputStream、StringBufferInputStream、FileInputStream、ObjectInputStream是基本的介质流,它们分别从Byte数组、StringBuffer、本地文件和对象中读取数据,PipedInputStream是从与其他线程共用的管道中读取数据。
他们都是具体的装饰对象,也就是上面的具体构件(ConcreteComponent)角色。
3)BufferedInputStream、DataInputStream是实际的装饰器对象。
也就是具体装饰(ConcreteDecorator)角色。
看到这里也许会有一些疑问,装饰角色呢,也就是那个抽象类去哪了,在这里我觉得FilterInputStream就是这个角色,不过它不是抽象类,在使用中也很少用到,姑且这么认为把。
上面说了,装饰角色会持有一个对抽象父类InputStream的引用来完成装饰模式。现在去验证下。
//构造时传入引用
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
//直接用父类的引用
public DataInputStream(InputStream in) {
super(in);
}
装饰模式之OutputStream(字节流)
从IO中输入字节流的继承图中可以看出。
1)OutputStream是所有输出字节流的父类,它是一个抽象类。
是个接口,也是上面提到的抽象构件(Component)角色。
2)ByteArrayOutputStream、FIleOutputStream是两种基本的介质,它们分别向Byte 数组,和本地文件中写入数据。PipedOutputStream是从与其他线程共用的管道中写入数据。
他们都是具体的装饰对象,也就是上面的具体构件(ConcreteComponent)角色。
3)BufferdOutputStream、DataOutputStream是实际的装饰器对象。
也就是具体装饰(ConcreteDecorator)角色。
原理同InputStream
字符输入流Reader
在上面的继承关系图中可以看出:
1、Reader是所有的输入字符流的父类,它是一个抽象类。
2、CharReader、StringReader 是两种基本的介质流,它们分别将Char数组、String中读取数据。PipedInputReader 是从与其他线程共用的管道中读取数据。
3、BuffereReader 很明显的是一个装饰器对象,它和其子类复制装饰其他Reader对象。
4、FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰。
字符输出流Writer
在上面的关系图中可以看出:
1、Writer 是所有输出字符流的父类,它是一个抽象类。
2、CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedInputWriter 是从与其他线程共用的管道中读取数据。
3、BuffereWriter 很明显是一个装饰器,他和其子类复制装饰其他Reader对象。
4、FilterWriter 和PrintStream 及其类似,功能和使用也非常相似。
区别与联系
· 读写单位的不同:字节流以字节(8bit)为单位。字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
· 处理对象不同:字节流可以处理任何类型的数据,如图片、avi等,而字符流只能处理字符类型的数据。
InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。
RandomAccessFile
1.既可以读也可以写
RandomAccessFile不属于InputStream和OutputStream类系。它是完全独立的类
2.可以指定位置读写
RandomAccessFile能在文件里面的前后移动,在文件里移动用seek()。可以用于多线程下载或多个线程同时写数据到文件。
总结
理解本篇文章最主要的还是对装饰器模式有所了解,了解之后才能构建体系,现在知道开头的一层层的嵌套是什么意思了把。。。
网友评论