-----------------------------------------------------------------------------------
FilterInputStream、FilterOutputStream 过滤器字节输入流、输出流,这里用到了装饰器模式,它的主要用途在于给一个对象动态的添加功能。
当我们在创建FilterInputStream、FilterOutputStream这两个类的实例时需要传入一个InputStream、OutPutStream的子类,比如:当构造FilterOutputStream时传递进去的是FileOutputStream,而FileOutputStream和FilterOutputStream实现的是同一个抽象类OutputStream,那么FilterOutputStrean对FileOutputStream的装饰对于客户端来说就是透明的,可以在FileOutputStream的方法执行之前或之后加上一些额外的操作来达到装饰的效果。
FilterInputStream、FilterOutputStream 仅仅是对InputStream、OutputStream中所有方法进行了重写,并且只是调用传入的InputStream、OutputStream子类的方法,话句话说就是没有对传入的低级字节输入流进行任何的装饰,它们的作用是为所有字节输入流的装饰类提供一个标准、一个类似于接口的作用,具体的装饰功能由FilterInputStream、FilterOutputStream的子类来完成。
-----------------------------------------------------------------------------------
FilterInputStream
类声明:public class FilterInputStream extends InputStream
位于java.io包下
官方对其说明:
A FilterInputStream contains some other input stream, which it uses as its basic source of data, possibly transforming the data along the way or providing additional functionality. The class FilterInputStream itself simply overrides all methods of InputStream with versions that pass all requests to the contained input stream. Subclasses of FilterInputStream may further override some of these methods and may also provide additional methods and fields.
(简单翻译:FilterInputStream包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。FilterInputStream类本身只是简单地重写那些将所有请求传递给所包含输入流的InputStream的所有方法。FilterInputStream的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。)
主要字段:
protected InputStream in; //要过滤的输入流
构造方法:
protected FilterInputStream(InputStream in)
主要方法:
- int available(): 返回输入流中还可以读取的字节个数.
- void close(): 关闭此输入流并释放与该流有关的系统资源.
- void mark(int readlimit): 在此输入流中标记当前的位置.
- boolean markSupported(): 检测此输入流是否支持mark和reset.
- int read(): 从输入流中读取数据的下一个字节.
- int read(byte[] b): 从输入流中读取一定数量的字节,并将其存储在字节数组b中
- int read(byte[] b,int off,int len): 从输入流中读取len个字节,并将其存储在字节数组b中off位置开始的地方
- void reset(): 将此流重新定位到最后一次对此输入流调用mark方法时的位置.
- long skip(long n): 跳过和丢弃此输入流中n个字节的数据.
源代码如下:
1 package java.io; 2 3 /** 4 * A <code>FilterInputStream</code> contains 5 * some other input stream, which it uses as 6 * its basic source of data, possibly transforming 7 * the data along the way or providing additional 8 * functionality. The class <code>FilterInputStream</code> 9 * itself simply overrides all methods of 10 * <code>InputStream</code> with versions that 11 * pass all requests to the contained input 12 * stream. Subclasses of <code>FilterInputStream</code> 13 * may further override some of these methods 14 * and may also provide additional methods 15 * and fields. 16 * 17 * @author Jonathan Payne 18 * @since JDK1.0 19 */ 20 public 21 class FilterInputStream extends InputStream { 22 /** 23 * The input stream to be filtered. 24 */ 25 protected volatile InputStream in; 26 27 /** 28 * Creates a <code>FilterInputStream</code> 29 * by assigning the argument <code>in</code> 30 * to the field <code>this.in</code> so as 31 * to remember it for later use. 32 * 33 * @param in the underlying input stream, or <code>null</code> if 34 * this instance is to be created without an underlying stream. 35 */ 36 protected FilterInputStream(InputStream in) { 37 this.in = in; 38 } 39 40 /** 41 * Reads the next byte of data from this input stream. The value 42 * byte is returned as an <code>int</code> in the range 43 * <code>0</code> to <code>255</code>. If no byte is available 44 * because the end of the stream has been reached, the value 45 * <code>-1</code> is returned. This method blocks until input data 46 * is available, the end of the stream is detected, or an exception 47 * is thrown. 48 * <p> 49 * This method 50 * simply performs <code>in.read()</code> and returns the result. 51 * 52 * @return the next byte of data, or <code>-1</code> if the end of the 53 * stream is reached. 54 * @exception IOException if an I/O error occurs. 55 * @see java.io.FilterInputStream#in 56 */ 57 public int read() throws IOException { 58 return in.read(); 59 } 60 61 /** 62 * Reads up to <code>byte.length</code> bytes of data from this 63 * input stream into an array of bytes. This method blocks until some 64 * input is available. 65 * <p> 66 * This method simply performs the call 67 * <code>read(b, 0, b.length)</code> and returns 68 * the result. It is important that it does 69 * <i>not</i> do <code>in.read(b)</code> instead; 70 * certain subclasses of <code>FilterInputStream</code> 71 * depend on the implementation strategy actually 72 * used. 73 * 74 * @param b the buffer into which the data is read. 75 * @return the total number of bytes read into the buffer, or 76 * <code>-1</code> if there is no more data because the end of 77 * the stream has been reached. 78 * @exception IOException if an I/O error occurs. 79 * @see java.io.FilterInputStream#read(byte[], int, int) 80 */ 81 public int read(byte b[]) throws IOException { 82 return read(b, 0, b.length); 83 } 84 85 /** 86 * Reads up to <code>len</code> bytes of data from this input stream 87 * into an array of bytes. If <code>len</code> is not zero, the method 88 * blocks until some input is available; otherwise, no 89 * bytes are read and <code>0</code> is returned. 90 * <p> 91 * This method simply performs <code>in.read(b, off, len)</code> 92 * and returns the result. 93 * 94 * @param b the buffer into which the data is read. 95 * @param off the start offset in the destination array <code>b</code> 96 * @param len the maximum number of bytes read. 97 * @return the total number of bytes read into the buffer, or 98 * <code>-1</code> if there is no more data because the end of 99 * the stream has been reached. 100 * @exception NullPointerException If <code>b</code> is <code>null</code>. 101 * @exception IndexOutOfBoundsException If <code>off</code> is negative, 102 * <code>len</code> is negative, or <code>len</code> is greater than 103 * <code>b.length - off</code> 104 * @exception IOException if an I/O error occurs. 105 * @see java.io.FilterInputStream#in 106 */ 107 public int read(byte b[], int off, int len) throws IOException { 108 return in.read(b, off, len); 109 } 110 111 /** 112 * Skips over and discards <code>n</code> bytes of data from the 113 * input stream. The <code>skip</code> method may, for a variety of 114 * reasons, end up skipping over some smaller number of bytes, 115 * possibly <code>0</code>. The actual number of bytes skipped is 116 * returned. 117 * <p> 118 * This method simply performs <code>in.skip(n)</code>. 119 * 120 * @param n the number of bytes to be skipped. 121 * @return the actual number of bytes skipped. 122 * @exception IOException if the stream does not support seek, 123 * or if some other I/O error occurs. 124 */ 125 public long skip(long n) throws IOException { 126 return in.skip(n); 127 } 128 129 /** 130 * Returns an estimate of the number of bytes that can be read (or 131 * skipped over) from this input stream without blocking by the next 132 * caller of a method for this input stream. The next caller might be 133 * the same thread or another thread. A single read or skip of this 134 * many bytes will not block, but may read or skip fewer bytes. 135 * <p> 136 * This method returns the result of {@link #in in}.available(). 137 * 138 * @return an estimate of the number of bytes that can be read (or skipped 139 * over) from this input stream without blocking. 140 * @exception IOException if an I/O error occurs. 141 */ 142 public int available() throws IOException { 143 return in.available(); 144 } 145 146 /** 147 * Closes this input stream and releases any system resources 148 * associated with the stream. 149 * This 150 * method simply performs <code>in.close()</code>. 151 * 152 * @exception IOException if an I/O error occurs. 153 * @see java.io.FilterInputStream#in 154 */ 155 public void close() throws IOException { 156 in.close(); 157 } 158 159 /** 160 * Marks the current position in this input stream. A subsequent 161 * call to the <code>reset</code> method repositions this stream at 162 * the last marked position so that subsequent reads re-read the same bytes. 163 * <p> 164 * The <code>readlimit</code> argument tells this input stream to 165 * allow that many bytes to be read before the mark position gets 166 * invalidated. 167 * <p> 168 * This method simply performs <code>in.mark(readlimit)</code>. 169 * 170 * @param readlimit the maximum limit of bytes that can be read before 171 * the mark position becomes invalid. 172 * @see java.io.FilterInputStream#in 173 * @see java.io.FilterInputStream#reset() 174 */ 175 public synchronized void mark(int readlimit) { 176 in.mark(readlimit); 177 } 178 179 /** 180 * Repositions this stream to the position at the time the 181 * <code>mark</code> method was last called on this input stream. 182 * <p> 183 * This method 184 * simply performs <code>in.reset()</code>. 185 * <p> 186 * Stream marks are intended to be used in 187 * situations where you need to read ahead a little to see what's in 188 * the stream. Often this is most easily done by invoking some 189 * general parser. If the stream is of the type handled by the 190 * parse, it just chugs along happily. If the stream is not of 191 * that type, the parser should toss an exception when it fails. 192 * If this happens within readlimit bytes, it allows the outer 193 * code to reset the stream and try another parser. 194 * 195 * @exception IOException if the stream has not been marked or if the 196 * mark has been invalidated. 197 * @see java.io.FilterInputStream#in 198 * @see java.io.FilterInputStream#mark(int) 199 */ 200 public synchronized void reset() throws IOException { 201 in.reset(); 202 } 203 204 /** 205 * Tests if this input stream supports the <code>mark</code> 206 * and <code>reset</code> methods. 207 * This method 208 * simply performs <code>in.markSupported()</code>. 209 * 210 * @return <code>true</code> if this stream type supports the 211 * <code>mark</code> and <code>reset</code> method; 212 * <code>false</code> otherwise. 213 * @see java.io.FilterInputStream#in 214 * @see java.io.InputStream#mark(int) 215 * @see java.io.InputStream#reset() 216 */ 217 public boolean markSupported() { 218 return in.markSupported(); 219 } 220 }