廖雪峰Java6 IO编程-2input和output-4Filter模式
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模式的更多相关文章
- 廖雪峰Java6 IO编程-2input和output-7序列化
1.序列化 序列化是指把一个Java对象变成二进制内容byte[] 序列化后可以把byte[]保存到文件中 序列化后可以把byte[]通过网络传输 一个Java对象要能序列化,必须实现Serializ ...
- 廖雪峰Java6 IO编程-2input和output-5操作zip
1.ZipInputStream是一种FilterInputStream 可以直接读取zip的内容 InputStream->FilterInputStream->InflateInput ...
- 廖雪峰Java6 IO编程-2input和output-6classpath资源
1.从classpath读取文件可以避免不同环境下文件路径不一致的问题. Windows和Linux关于路径的表示不一致 Windows:C:\conf\default.properties Linu ...
- 廖雪峰Java6 IO编程-3Reader和Writer-2Writer
1.java.io.Writer和java.io.OutputStream的区别 OutputStream Writer 字节流,以byte为单位 字符流,以char为单位 写入字节(0-255):v ...
- 廖雪峰Java6 IO编程-3Reader和Writer-1Reader
1.java.io.Reader和java.io.InputStream的区别 InputStream Reader 字节流,以byte为单位 字符流,以char为单位 读取字节(-1,0-255): ...
- 廖雪峰Java13网络编程-1Socket编程-2TCP编程
1. Socket 在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据 ...
- 廖雪峰Java13网络编程-3其他-1HTTP编程
1.HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 * 使用浏览器浏览网页和服务器交互使用的就是 ...
- 廖雪峰Java13网络编程-1Socket编程-5UDP编程
1. UDP编程: 不需要建立连接 可以直接发送和接收数据 1.1 客户端 DatagramSocket sock = new DatagramSocket(){} sock.connect(addr ...
- 廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程
TCP多线程编程 一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信. 因此服务器端,当我们打开一个Socket以后,通 ...
随机推荐
- 【HDOJ4857】【反向拓扑排序】
http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others) Memory L ...
- Liunx----vi编辑器
关于vi编辑器基本的用法总结如下: vi是linux下的一款文编编辑器. 进入vi的方法:在系统启动起来后,直接键入vi或vi 文件名: 进去后输入内容方法:输入a或i,切换到编辑模式: 退出编辑模式 ...
- C结构体变量2种运算(比如链表的结点)(区别与java)
a结构体变量,只能做两种运算, 整体引用(赋值,参数传递) 或访问成员(点运算—地址方式简化,地址方式)(见最后的图片) case万: 结论:java里面的class Node : Node p; p ...
- Java数组逆序排列
//逆序排列原理 /* A: 数组逆序原理* a: 题目分析* 通过观察发现,本题目要实现原数组元素倒序存放操作.即原数组存储元素为{12,69,852,25,89,588},逆序后为原数组存储元素变 ...
- MySQL使用游标
MySQL检所操作返回一组称为结果集的行,游标是一个存储在MySQL服务器上的数据库查询,它不是一条select语句,而是被该语句所检索出来的结果集.只能用于存出过程. 声明(定义)游标,这个过程没有 ...
- MySQL中or与in
and和or mysql允许多个where子句,用and和or可以使用多个子句.and比or有更高的优先级.任何时候使用and和or都应使用圆括号操作符来明确的分组操作. in 圆括号在where子句 ...
- 【HI3520DV200】sample
1.vdec不支持1280x720,支持640x480及以下
- 短小而精悍的JsvaScript函数
1. 回到顶部, 使用浏览器的刷新频率 requestAnimationFrame 来实现的 const scrollToTop = () => { const c = document.doc ...
- COLUMN_FORMAT 的值:FIXED、DYNAMIC、DEFAULT 的区别(待补充)
参考===MySQL 建表语句 create table 中的列定义: column_definition: data_type [NOT NULL | NULL] [DEFAULT default_ ...
- node api 之:process - 进程
process 对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程. 因为是全局变量,所以无需使用 require().