你好!欢迎阅读我的博文,你可以跳转到我的个人博客网站,会有更好的排版效果和功能。

此外,本篇博文为本人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装饰器模式的大家族的更多相关文章

  1. java设计模式之装饰器模式以及在java中作用

    在JAVA I/O类库里有很多不同的功能组合情况,这些不同的功能组合都是使用装饰器模式实现的,下面以FilterInputStream为例介绍装饰器模式的使用  FilterInputStream和F ...

  2. Java设计模式系列-装饰器模式

    原创文章,转载请标注出处:<Java设计模式系列-装饰器模式> 一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是 ...

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

    顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...

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

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

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

    1.装饰器模式的定义(保持接口,扩展功能) Decorate装饰器,顾名思义,就是动态的给一个对象添加一些额外的职责,就好比对房子进行装修一样. 2.装饰器模式的特征 具有一个装饰对象. 必须拥有与被 ...

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

    装饰器模式的作用 在不修改原先对象核心的功能的情况下,对功能进行增强. 增强对象的功能的途径 通过类继承的方式,对父对象进行增强操作,例如造车是父类,改装跑车,跑车加大灯,改装房车,房车加私人电影院. ...

  7. 深入探索Java设计模式(三)之装饰器模式

    装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类.这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用.本文是在学习完优锐课JAVA架构VIP课程—[框架源码专题 ...

  8. 面向对象程序设计(OOP设计模式)-结构型模式之装饰器模式的应用与实现

    课程名称:程序设计方法学 实验4:OOP设计模式-结构型模式的应用与实现 时间:2015年11月18日星期三,第3.4节 地点:理1#208 一.实验目的 加深对结构型设计模式的理解以及在开发中的实际 ...

  9. 装饰器模式-Decerator

    一.定义 装饰器模式又叫做包装模式(Wrapper).装饰器模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 在以下情况下应该使用装饰器模式: 1.需要扩展一个类的功能,或给一个类增 ...

随机推荐

  1. Tp-link路由器怎么设置端口映射 内网端口映射听语音

    https://jingyan.baidu.com/article/ca00d56c710ef9e99eebcf85.html 只有一台能上网的电脑就可以自己免费搭建服务器,本经验简单介绍家用tp-l ...

  2. [sklearn]官方例程-Imputing missing values before building an estimator 随机填充缺失值

    官方链接:http://scikit-learn.org/dev/auto_examples/plot_missing_values.html#sphx-glr-auto-examples-plot- ...

  3. android 基础02 - Activity 的生命周期及状态

    返回栈 Android 中的 Activity 是可以层叠的,当我们启动一个新的 Activity 时,就会覆盖在原有的 Activity 之上, 点击 Back 会销毁当前 Activity,下面的 ...

  4. 【开发技术】Eclipse设置软tab(用4个空格字符代替)及默认utf-8文件编码(unix)

    Eclipse设置软tab(用4个空格字符代替)及默认utf-8文件编码(unix) 本文摘要: 1.如何配置Eclipse中编辑器支持softtab(用数个空格字符代替默认的tab缩进): 2.如何 ...

  5. 了解JDK 6和JDK 7中substring的原理及区别

    substring(int beginIndex, int endIndex)方法在jdk 6和jdk 7中的实现是不同的.了解他们的区别可以帮助你更好的使用他.为简单起见,后文中用substring ...

  6. Arduino库函数中文说明

    #define 常量名 常量值 % 取模运算符 String abc  /  char abc[n]  定义字符串 pinMode(pin,mode);  用于引脚的初始化  mode包括 INPUT ...

  7. 共轭梯度算法求最小值-scipy

    # coding=utf-8 #共轭梯度算法求最小值 import numpy as np from scipy import optimize def f(x, *args): u, v = x a ...

  8. JAVA中double类型运算结果异常的解决

    问题: 对两个double类型的值进行运算,有时会出现结果值异常的问题.比如: System.out.println(19.99+20); System.out.println(1.0-0.66); ...

  9. android软键盘的显示和隐藏

    显示: InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); imm.toggle ...

  10. RChain总体架构图

    RChain是我研究区块链依赖发现的和我最契合的(主要是用scala写的),在架构上吞吐率和扩展性也是最好,未来是真正有可能实现在它官网上宣称的能够承载facebook一样的规模,具有和visa一样的 ...