Java中InputStream装饰器模式的大家族
你好!欢迎阅读我的博文,你可以跳转到我的个人博客网站,会有更好的排版效果和功能。
此外,本篇博文为本人Pushy原创,如需转载请注明出处:https://pushy.site/posts/1519819757
本文写在po主初学JAVA时,在学习inputStream摸不着头脑,受Java IO-InputStream家族 -装饰者模式一文启发,所以在理清思路时写下本文。因为初学,如有错误,望指正。
因为和输入流与之对应的还有输出流(即OutputStream),在此只针对输入流InputStream讨论。
1. 家族老大:
一说起家族中的老大,InputStream自然是当仁不让,在java的输入流操作的类中,衍生出的基本子类有,可以理解为这些都是InputStream它的孩子(子类):

InputStream作为所有输入流中的超类,包含从输入流读取数据的基本方法,所有的具体类都包含了这些方法,例如read()方法,它将读取一个字节并将其以int类型返回,当到达输入流的结尾时,返回-1,因此我们常常这样操作:
byte data;
while ((data = (byte) bis.read()) != -1) {
// 当没有达到输入流的结尾时,继续读取并打印转换成char类型的字符:
System.out.print((char) data);
}
这段代码不了解不要紧,现在我们开始正式介绍InputStream家族。
2. 家族孩子:
家族中的子类各司其职,老大FileInputStream处理文件流,老二ByteArrayInputStream处理字节数组流...
例如,我们来看下老大是怎么工作的:
import java.io.*;
import java.util.Date;
public class FileInputStreamTest {
public static void main(String[] args) throws Exception{
try {
// 创建FileInputStream对象:
FileInputStream fis = new FileInputStream("E:\\text.txt");
// 得到起始时间:
long start = System.currentTimeMillis( );
byte byteData;
while ((byteData = (byte) bis.read()) != -1) {
System.out.print((char) byteData);
}
// 得到读取后的结束时间:
long end = System.currentTimeMillis( );
// 计算出读取的时间:
long diff = end - start;
System.out.println("读取的时间时间共:" + diff);
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
工作完成后,我们可以得到老大干完活的花费的时间为:1097,但是家族老大嫌这家伙干活太慢了。老大无奈,叫来了它的弟弟老二BufferedInputStream,俗话说啊,兄弟齐心,其利断金。果不其然,兄弟俩一块干活效率果然加快了不少:
在如下的代码中我们可以看到,通过将FileInputStream放到BufferedInputStream中的构造方法中去创建BufferedInputStream对象,这样FileInputStream也就具有了缓存的输入流功能。
public class BufInputStream {
public static void main(String[] args) throws Exception{
try {
// 通过缓冲区数据向输入流添加功能,维护一个内部缓冲区以存储从底层输入流读取的字节:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\text.txt"));
long start = System.currentTimeMillis( );
byte byteData;
while ((byteData = (byte) fis.read()) != -1) {
System.out.print((char) byteData);
}
long end = System.currentTimeMillis( );
long diff = end - start;
System.out.println("读取的时间时间共:" + diff);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
现在我们来看下兄弟俩一块工作花费的时间吧:281。嘿!果然快了不少!看来增加缓冲流的功能的效果的确十分明显。
这下老二在家族的名声增大了不少,许多的兄弟都找他搭档干活了。
3. 总结:
通过上文的假设,我们可以明白了在io-InputStream的家族中,采用了装饰者的设计模式,即不改变原类文件和使用继承的前提下,动态地扩展一个对象的功能(比如说这里的支持缓冲流),通过创建一个包装对象(这里的BufferedInputStream),也就是装饰包裹真实的对象。

例如我们还可以也ByteArrayInputStream中修饰PushbackInputStream类:
PushbackInputStream pbi = new PushbackInputStream (new ByteArrayInputStream(b));
ByteArrayInputStream是处理字节数组流;PushbackInputStream是向输入流中添加功能,允许使用unread()方法推回读取的字节。这样我们就可以使用pbi对象处理字节数组,还具有推回读取字节的功能了:
import java.io.*;
public class BAStreamAndPBStream {
public static void main(String[] args) throws IOException{
byte[] b = {1,2,3};
PushbackInputStream pbi = new PushbackInputStream (new ByteArrayInputStream(b));
int result;
while ((result = pbi.read()) != -1) {
System.out.print(result + " ");
pbi.unread(result);
pbi.read();
System.out.print(result + " ");
}
pbi.close();
}
}
// 运行结果为:
// 1 1 2 2 3 3
好了,有关InputStream的大家族到这里介绍完了!如果你还有不明白的,可以阅读一下文章Java IO-InputStream家族 -装饰者模式。
Java中InputStream装饰器模式的大家族的更多相关文章
- java设计模式之装饰器模式以及在java中作用
在JAVA I/O类库里有很多不同的功能组合情况,这些不同的功能组合都是使用装饰器模式实现的,下面以FilterInputStream为例介绍装饰器模式的使用 FilterInputStream和F ...
- Java设计模式系列-装饰器模式
原创文章,转载请标注出处:<Java设计模式系列-装饰器模式> 一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是 ...
- java设计模式之七装饰器模式(Decorator)
顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...
- java设计模式之 装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...
- Java设计模式之装饰器模式
1.装饰器模式的定义(保持接口,扩展功能) Decorate装饰器,顾名思义,就是动态的给一个对象添加一些额外的职责,就好比对房子进行装修一样. 2.装饰器模式的特征 具有一个装饰对象. 必须拥有与被 ...
- java 设计模式 之 装饰器模式
装饰器模式的作用 在不修改原先对象核心的功能的情况下,对功能进行增强. 增强对象的功能的途径 通过类继承的方式,对父对象进行增强操作,例如造车是父类,改装跑车,跑车加大灯,改装房车,房车加私人电影院. ...
- 深入探索Java设计模式(三)之装饰器模式
装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类.这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用.本文是在学习完优锐课JAVA架构VIP课程—[框架源码专题 ...
- 面向对象程序设计(OOP设计模式)-结构型模式之装饰器模式的应用与实现
课程名称:程序设计方法学 实验4:OOP设计模式-结构型模式的应用与实现 时间:2015年11月18日星期三,第3.4节 地点:理1#208 一.实验目的 加深对结构型设计模式的理解以及在开发中的实际 ...
- 装饰器模式-Decerator
一.定义 装饰器模式又叫做包装模式(Wrapper).装饰器模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 在以下情况下应该使用装饰器模式: 1.需要扩展一个类的功能,或给一个类增 ...
随机推荐
- HTML 5 video 视频标签全属性详解
http://www.cnblogs.com/kiter/archive/2013/02/25/2932157.html 现在如果要在页面中使用video标签,需要考虑三种情况,支持Ogg Theor ...
- 《并行程序设计导论》——OpenMP
OpenMP看着很好,实际上坑很多. 如果真的要求性能和利用率,还是专门写代码吧.而且MS的VS里只有2.X的版本.
- C#进行CAD二次开发环境配置
最近被公司分配到了做CAD二次开发.也是初次接触这方面的东西,其实是有些无从下手的感觉.因为公司这边也没有人有时间带我,只能是自己看书,然后再写一些Demo,再结合实际的应用来一点点的学习.废话不多说 ...
- hibernate.dialect是干嘛用的?
dialect[ˈdaɪəlekt]就是“方言”,因为hibernate是要把Java对象转换成关系数据库来描述的,而关系数据库虽然有一些统一的标准,如SQL-92等,但是实际上各数据库如Oracle ...
- DALI 2.0解码模块
DALI2.0调光解码模块使用手册 一.概述(联系人:张先生,电话:13923882807,QQ:813267849) 欢迎使用本公司的DALI 2.0解码模块,该模块支持"DALI第二套协 ...
- mysql 分组和聚合函数
mysql 分组和聚合函数 Mysql 聚集函数有5个: 1.COUNT() 记录个数(count(1),count(*)统计表中行数,count(列名)统计列中非null数) 2.MAX() 最大值 ...
- ASP.NET没有魔法——ASP.NET MVC 模型绑定
在My Blog中已经有了文章管理功能,可以发布和修改文章,但是对于文章内容来说,这里缺少最重要的排版功能,如果没有排版的博客很大程度上是无法阅读的,由于文章是通过浏览器查看的,所以文章的排版其实与网 ...
- Springmvc 并发访问的线程安全性问题
首先对于spring的IOC来说,对象是由Spring来帮我们管理,也就是在Spring启动的时候,在Spring容器中,由Spring给我们创建的,Spring会帮我们维护,一般都是单例的,也就是一 ...
- docker结合jenkins、gitlab实现.netcore的持续集成实践
本文的目标是实现下图基于ASP NET Core的实践 运行环境 Cent OS 7 vs code .net core cmder 运行docker,设置docker镜像加速器,不然国内下载imag ...
- Hystrix-request collapsing(请求合并)
介绍: Hystrix的请求合并就是把重复的请求批量的用一个HystrixCommand命令去执行,以减少通信消耗和线程数的占用.Hystrix的请求合并用到了HystrixCollapser这个抽象 ...