Java_io体系之FilterInputStream/FilterOutputStream简介、走进源码及示例——07

Java_io体系之FilterInputStream/FilterOutputStream简介、走进源码及示例——07


一:FilterInputStream


1、       类功能简介:


         过滤器字节输入流、这里不得不提到一种设计模式:Decorator模式、Decorator模式又名包装器(Wrapper),它的主要用途在于给一个对象动态的添加一些额外的职责。与生成子类相比,它更具有灵活性。

  有时候,我们需要为一个对象而不是整个类添加一些新的功能,比如,给一个文本区添加一个滚动条的功能。我们可以使用继承机制来实现这一功能,但是这种方法不够灵活,我们无法控制文本区加滚动条的方式和时机。而且当文本区需要添加更多的功能时,比如边框等,需要创建新的类,而当需要组合使用这些功能时无疑将会引起类的爆炸。

  我们可以使用一种更为灵活的方法,就是把文本区嵌入到滚动条中。而这个滚动条的类就相当于对文本区的一个装饰。这个装饰(滚动条)必须与被装饰的组件(文本区)继承自同一个接口,这样,用户就不必关心装饰的实现,因为这对他们来说是透明的。装饰会将用户的请求转发给相应的组件(即调用相关的方法),并可能在转发的前后做一些额外的动作(如添加滚动条)。通过这种方法,我们可以根据组合对文本区嵌套不同的装饰,从而添加任意多的功能。这种动态的对对象添加功能的方法不会引起类的爆炸,也具有了更多的灵活性。

  以上的方法就是Decorator模式,它通过给对象添加装饰来动态的添加新的功能。

Exp:

            当构造FilterInputStream传递进来的是ByteArrayInputStream、因为FilterInputStream与ByteArrayInputStream实现的是同一接口InputStream、那么FileterInputStream对ByteArrayInputStream的装饰对于使用者来说是透明的、他可以在ByteArrayInputStream从父类继承的方法执行之前或者之后进行一些额外操作、实现装饰作用、这里不得不提一句、FilterInputStream仅仅对对InputStream中所有方法进行了重写、并且只调用传入的InputStream子类(一般是低级字节输入流)的那些实现InputStream中的方法、换句话说就是没有对传入的低级字节输入流进行任何的装饰、他的作用是为所有作为装饰类的字节输入流提供一个标准、一个类似于接口的作用。具体的装饰由其子类来完成。

       更多内容可以看看前面的:java——IO设计模式:http://blog.csdn.net/crave_shy/article/details/14613423


2、       FilterInputStreamAPI简介:


A:关键字段

    //接收构造函数传递进来的 InputStream具体实现类。
    protected volatile InputStream in;

B:构造方法

    // 根据传入的InputStream具体实现类创建FilterInputStream

    protected FilterInputStream(InputStream in) {
    	this.in = in;
    }

C:一般方法

	int avaliable();查看当前流中可供读取的字节数。
	
	void close();关闭当前流、释放所有与当前流有关的资源。
	
	synchronized void mark(int readlimit);标记当前流的读取的位子。
	
	boolean markSupport();查看当前流是否支持mark。
	
	int read();读取当前流中的下一个字节、并以整数形式返回、若读取到文件结尾则返回-1。
	
	int read(byte[] b);将当前流中的字节读取到字节数组b中、返回实际读取的字节数
	
	int read(byte[] b, int off, int len);将当前流中的len个字节读取到从下标off开始存放的字节数组b中。
	
	synchronized reset();重置当前流的读取位置到最后一次调用mark方法标记的位置。
	
	long skip(long n);跳过(抛弃)当前流中n个字节。返回实际抛弃的字节数。


3、       源码分析:


package com.chy.io.original.code;

import java.io.IOException;

/**
 * FileterInputStream 过滤器字节输入流    、本身什么事都没有做、只是简单的重写InputStream的所有方法。
 */
public class FilterInputStream extends InputStream {
    /**
     * 接收构造函数传递进来的 InputStream具体实现类。
     * 至于 volatile 关键字的意义 参见:http://blog.csdn.net/crave_shy/article/details/14610155 
     */
    protected volatile InputStream in;

    /**
     * 根据传入的InputStream具体实现类创建FilterInputStream、并将此实现类赋给全局变量 in、方便重写此实现类从InputStream继承的或重写的所有方法。
     */
    protected FilterInputStream(InputStream in) {
    	this.in = in;
    }

    /**
     * 具体InputStream实现类的read()方法、若子类自己实现的、则是子类的、若子类没有实现则用的是InputStream本身的方法。
     * 下面的方法一样。若有不明白的可见前面的InputStream源码分析。
     */
    public int read() throws IOException {
    	return in.read();
    }
    
    public int read(byte b[]) throws IOException {
    	return read(b, 0, b.length);
    }

    public int read(byte b[], int off, int len) throws IOException {
    	return in.read(b, off, len);
    }

    public long skip(long n) throws IOException {
    	return in.skip(n);
    }

    public int available() throws IOException {
    	return in.available();
    }

    public void close() throws IOException {
    	in.close();
    }

    public synchronized void mark(int readlimit) {
    	in.mark(readlimit);
    }

    public synchronized void reset() throws IOException {
    	in.reset();
    }
    public boolean markSupported() {
    	return in.markSupported();
    }
}



4、       实例演示:


            因为其只是一个标准、其方法都是调用传入的InputStream实现类的方法、意义大过于作用、所以这里暂不提供实例、会在有实际装饰效果的类中提供实例、比如后面的DataInputStream、BufferedInputStream、等装饰类的文章中贴出。

 

二:FilterOutputStream


1、       类功能简介:


             过滤字节输出流、与此类是过滤输出流的所有类的超类。这些流位于已存在的输出流(基础输出流)之上,它们将已存在的输出流作为其基本数据接收器,但可能直接传输数据或提供一些额外的功能。

       FilterOutputStream 类本身只是简单地重写那些将所有请求传递给所包含输出流的 OutputStream 的所有方法。FilterOutputStream 的子类可进一步地重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。这是API中关于此流的原话、与对上面FilterInputStream的理解做个对比、多方面的去理解、对比更可以加深印象。

 

2、       FilterInputStreamAPI简介:


A:关键字段

    //传入的OutputStream实现类的引用
    protected OutputStream out;

B:构造方法
    //通过传入的OutputStream实现类构造FilterOutputStream
    public FilterOutputStream(OutputStream out) {
    	this.out = out;
    }

C:一般方法
	void write(byte b);将一个字节写入到当前输出流管道中。
	
	void write(byte[] b);将字节数组b中所有字节写入到当前输出流管道中。
	
	void write(byte[] b, int off, int len);将字节数组b从下标off开始、len个字节写入当前输出流管道中	
	
	void flush();flush当前流、将当前流中的所有数据冲刷到目的地中。
	
	void close();关闭当前流、释放与当前流有关的所有资源。


3、       源码分析:


package com.chy.io.original.code;

import java.io.IOException;

/**
 * 与FilterOutputStream基本相同、
 */
public class FilterOutputStream extends OutputStream {
    /**
     * 与FileterInputStream 的区别就是不再是volatile
     */
    protected OutputStream out;

    //通过传入的OutputStream实现类构造FilterOutputStream
    public FilterOutputStream(OutputStream out) {
    	this.out = out;
    }

    public void write(int b) throws IOException {
    	out.write(b);
    }

    public void write(byte b[]) throws IOException {
    	write(b, 0, b.length);
    }

    public void write(byte b[], int off, int len) throws IOException {
		if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
		    throw new IndexOutOfBoundsException();
	
		for (int i = 0 ; i < len ; i++) {
		    write(b[off + i]);
		}
    }

    public void flush() throws IOException {
    	out.flush();
    }

    /**
     * 关闭此流之前会flush一下。
     */
    public void close() throws IOException {
		try {
		  flush();
		} catch (IOException ignored) {
		}
		out.close();
    }
}

4、       实例演示:


            因为其只是一个标准、其方法都是调用传入的InputStream实现类的方法、意义大过于作用、所以这里暂不提供实例、会在有实际装饰效果的类中提供实例、比如后面的DataInputStream、BufferedInputStream、等装饰类的文章中贴出。

总结:

       这一篇没有什么实际的东西、但是他是代表了所有装饰类的一个标准、和实现原理、对我们以后理解接下来的DataInputStream、BufferedInputStream等有很大的帮助、并且有一个使用到的设计模式也值得一提、但也没有针对设计模式长篇大论、毕竟主题不是设计模式、有关此设计模式在IO流中的应用可以看另一篇关于它的文章、FilterInputStream、FilterOutputStream两个类也为我们揭示了一个现象、就是多对java基础类库去应用、深入源码的实现、分析设计原理和过程不但对掌握基础有很好的帮助、也可以潜移默化的影响着我们的思维、让我们更“专业”。


更多IO内容:java_io 体系之目录


  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值