1.JDK提供的InputStream分为两类:

  • 直接提供数据的InputStream

    * FileInputStream:从文件读取

    * ServletInputStream:从HTTP请求读取数据

    * Socket.getInputStream():从TCP连接读取数据
  • 提供额外附加功能的FilterInputStream

    * 如果要给FileInputStream添加缓冲功能:

    • BufferedFileInputStream extends FileInputStream
*    如果要给FileInputStream添加计算机签名的功能:
* DigestFileInputStream extends FileInputStream
* 如果要给FileInputStream添加加密/解密功能:
* CipherFileInputStream extends FileInputStream
  • 组合功能而非继承的设计模式称为Filter模式(或者Decorator模式)
  • 通过少量的类实现了各种功能的组合
//演示代码
InputStream input = new GZIPInputStream(//直接读取解压缩包的内容
new BufferedInputStream(//提供缓冲的功能
new FileInputStream("test.gz")));

廖雪峰示例中的CountInputStream有错误,当读取完毕后,返回-1,而count再读取完毕后,会减1,导致结果不一样。运行结果如下。只需要将count的初始值设置为1即可。
```#java
public class CountInputStream extends FilterInputStream {
int count=0;
public CountInputStream(InputStream in) {
super(in);
}
//重写read方法,使用count计数
public int read(byte[] b,int off,int len) throws IOException {
int n = super.read(b,off,len);
count += n;
System.out.println(count);
return n;//最后返回-1,count-1
}
}

```#java
public class Main {
static void printCount1(List<Integer> list) throws IOException{
try(InputStream input = new GZIPInputStream(
new BufferedInputStream(
new FileInputStream("./src/main/java/com/testList/test.gz")))){
byte[] buffer = new byte[1024];//创建竹筒
int count=0;
int n ;
while((n=input.read(buffer))!=-1){
count += n;
list.add(n);
}
System.out.println("直接读取的和:"+count);
System.out.println("直接读取得到的集合的和"+getSum(list));
}
}
static void printCount2(List<Integer> list) throws IOException{
try(CountInputStream input = new CountInputStream(
new GZIPInputStream(
new BufferedInputStream(
new FileInputStream("./src/main/java/com/testList/test.gz"))))){
byte[] buffer = new byte[1024];
int n;
while((n=input.read(buffer))!=-1){
list.add(n);
// System.out.println();
}
System.out.println("通过CountInputStream获取的和:"+input.count);
System.out.println("通过CountInputStream获取的集合的和:"+getSum(list));
}
}
static Integer getSum(List<Integer> list){
int sum = 0;
for(int i=0;i<list.size();i++){
sum += list.get(i);
}
return sum;
}
public static void main(String[] args) throws IOException {
List<Integer> list1 = new LinkedList<>();
List<Integer> list2 = new LinkedList<>();
printCount2(list2);
printCount1(list1);
//从结果
System.out.println(list1);
}
}

2.总结

  • Java IO使用Filter模式为InputStream/OutputStream增加功能
  • 可以把一个InputStream和任意FilterInputStream组合
  • 可以把一个OutputStream和任意FilterOutputStream组合
  • Filter模式可以在运行期动态增加功能(又成Decorator模式)

廖雪峰Java6 IO编程-2input和output-4Filter模式的更多相关文章

  1. 廖雪峰Java6 IO编程-2input和output-7序列化

    1.序列化 序列化是指把一个Java对象变成二进制内容byte[] 序列化后可以把byte[]保存到文件中 序列化后可以把byte[]通过网络传输 一个Java对象要能序列化,必须实现Serializ ...

  2. 廖雪峰Java6 IO编程-2input和output-5操作zip

    1.ZipInputStream是一种FilterInputStream 可以直接读取zip的内容 InputStream->FilterInputStream->InflateInput ...

  3. 廖雪峰Java6 IO编程-2input和output-6classpath资源

    1.从classpath读取文件可以避免不同环境下文件路径不一致的问题. Windows和Linux关于路径的表示不一致 Windows:C:\conf\default.properties Linu ...

  4. 廖雪峰Java6 IO编程-3Reader和Writer-2Writer

    1.java.io.Writer和java.io.OutputStream的区别 OutputStream Writer 字节流,以byte为单位 字符流,以char为单位 写入字节(0-255):v ...

  5. 廖雪峰Java6 IO编程-3Reader和Writer-1Reader

    1.java.io.Reader和java.io.InputStream的区别 InputStream Reader 字节流,以byte为单位 字符流,以char为单位 读取字节(-1,0-255): ...

  6. 廖雪峰Java13网络编程-1Socket编程-2TCP编程

    1. Socket 在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据 ...

  7. 廖雪峰Java13网络编程-3其他-1HTTP编程

    1.HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 * 使用浏览器浏览网页和服务器交互使用的就是 ...

  8. 廖雪峰Java13网络编程-1Socket编程-5UDP编程

    1. UDP编程: 不需要建立连接 可以直接发送和接收数据 1.1 客户端 DatagramSocket sock = new DatagramSocket(){} sock.connect(addr ...

  9. 廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

    TCP多线程编程 一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信. 因此服务器端,当我们打开一个Socket以后,通 ...

随机推荐

  1. Java中动态获取项目根目录的绝对路径

    https://www.cnblogs.com/zhouqing/archive/2012/11/10/2757774.html 序言 在开发过程中经常会用到读写文件,其中就必然涉及路径问题.使用固定 ...

  2. 【BZOJ1213】高精度开根

    python是坠吼的! 原题: 不贴原题,就是高精度开根,结果向下取整 首先二分答案,高精度嘛……python即可 二分右端点设为n会T掉,需要先倍增一个r,while(r **m <= n) ...

  3. CH#46A 磁力块

    题意 磁力块 CH Round #46 - 「Adera 8」杯NOI模拟赛 描述 在一片广袤无垠的原野上,散落着N块磁石.每个磁石的性质可以用一个五元组(x,y,m,p,r)描述,其中x,y表示其坐 ...

  4. S老师 破坏神学习

    代码质量不高 就不整理了 发上来留个纪念 表示自己写过了 数据库:MySQL,服务端:PhotonServer 视频:https://pan.baidu.com/s/1i4ROaRr 客户端:http ...

  5. More C++ Idioms

    Table of Contents Note: synonyms for each idiom are listed in parentheses. Adapter Template TODO Add ...

  6. php格式化数字:位数不足前面加0补足

    <?php $var=sprintf("%02d", 2);//生成2位数,不足前面补0 echo $var;//结果为02 ?> 參考:https://blog.cs ...

  7. django ajax报错解决:You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set.

    Django版本号:1.11.15 django中ajax请求报错:You called this URL via POST, but the URL doesn't end in a slash a ...

  8. py-day1-5 python 分割 、 字母大小转换

    # partition() 分割为3段 从左往右遇见的第一个开始 test = 'bassaiwoll' v = test.partition('s') print(v) ('ba', 's', 's ...

  9. Zookeeper 四字命令 Four Letter Words

    1.zk可以通过它自身提供的简写命令来服务器进行交互 需要使用到nc命令,安装yum install nc echo  [commond] | nc [ip] [port] 2.[stat]  查看z ...

  10. NET设计模式 第二部分 行为型模式(16):命令模式(Command Pattern)

    命令模式(Command Pattern) ——.NET设计模式系列之十七 TerryLee,2006年7月 概述 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合,比 ...