因为和输入流与之对应的还有输出流(即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 

========================================Talk is cheap, show me the code=======================================

Java中InputStream装饰器模式的大家族相关推荐

  1. java中的装饰者模式[63]

    java中的装饰者模式[63] 文章目录 java中的装饰者模式[63] 一.什么是装饰者模式? 二.装饰者模式要点 三.代码演示 四.小结 一.什么是装饰者模式? **1.意图:**动态的给一个对象 ...

  2. 【源码分析设计模式 5】Java I/O系统中的装饰器模式

    一.基本介绍 动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 二.装饰器模式的结构 1.Component,抽象构件 Component是一个接口或者抽象类,是定义我们 ...

  3. Java中的装饰器设计模式

    装饰器设计模式允许在运行时将附加职责或行为动态附加到对象. 它是一种结构模式,利用聚合来组合这些行为. 在本教程中,我们将学习实现装饰器模式. UML图: 让我们从装饰器模式的UML表示开始: Con ...

  4. Java 8的装饰器模式

    在最近的一篇文章中,我描述了装饰器模式如何拯救了我的一天. 我给出了一个小代码段,其中包含创建装饰器的最简单方法,但承诺Java 8会有更好的方法. 这里是: 用Java 8装饰 HyperlinkL ...

  5. java设计模式之装饰器模式

    一.装饰器模式简介 装饰器模式可以动态给一个对象添加一些额外的职责,同时又不改变其结构.就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活.这种模式创建了一个装饰 ...

  6. 用实际的软件编程示例解释C#中的装饰器模式

    目录 背景 使用代码 兴趣点 下载演示-5.6 KB 背景 GoF定义:动态将附加职责附加到对象.装饰器为子类提供了灵活的替代方案,以扩展功能. 此模式支持SOLID 的"开-闭" ...

  7. java设计模式之 装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  8. (设计模式七)java设计模式之装饰器模式

    一.简介: 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类 ...

  9. Java 设计模式之装饰器模式

    装饰器模式用于给原有对象增加新功能的场景, 拿食物冰淇淋,香草巧克力作为例子,给冰淇淋加香草,或者加巧克力,或者加香草和巧克力. 首先定义一个食物接口: /*** 装饰类和被装饰类共同继承的抽象类* ...

最新文章

  1. Mysql中的递归层次查询(父子查询,无限极查询)
  2. JDK 7的算法和数据结构
  3. Puppet 之 模板和模块
  4. 写Rap,编菜谱,你画我猜……这些 AI demo 我可以玩一天!
  5. 关于内存的最后一个难点--the paged and the non-paged pool
  6. php基础-基本语法
  7. FISCO BCOS Transaction execution error合约执行失败原因
  8. 基于FPGA的智能家具之PM2.5传感器,温湿度传感器驱动设计
  9. 华为交换机忘记密码怎么办
  10. 火狐浏览器的安装及配置
  11. Hexo图片外链生成专用文章
  12. 基于 FPGA 的高级数字电路设计(7)单口 RAM、同步 FIFO、异步 FIFO 设计
  13. 笔记:C#_对象池_异常代码: c0000005
  14. cascade down_cascade是什么意思_cascade的翻译_音标_读音_用法_例句_爱词霸在线词典...
  15. 同浏览器 不同窗口 共享session 解决
  16. 牛顿3种方法解重根情形对比
  17. vue 页面保留缓存和清除缓存
  18. 采样坦克4音色编辑器-SampleTank Editor v4.0.0 WiN-MAC
  19. ODOO15固定资产管理系统解决方案(原创)
  20. AOC冠捷显示器无法保修

热门文章

  1. java请求传参方式的总结
  2. 2016年8月25日 星期四 --出埃及记 Exodus 16:26
  3. 谷歌自研芯片Tensor重磅来袭:“机器学习的里程碑”
  4. pyDes 库 DES 与 3DES 加解密
  5. c语言程序立体几何计算机,立体几何教学中巧妙利用信息技术 -----培养高中学生数学学习的兴趣   张芬     2014年11月10日...
  6. docker containers status显示Removal In Progress
  7. 用于土地使用和土地覆盖分类的landsat8的OLI波段组合的选择
  8. Day09.面向对象进阶
  9. 极端行情下,如何通过期权做好风险管理? | TI对话首席
  10. MySQL---DDL语句、DML语句与DCL语句