目录
简介
/**
* SequenceInputStream表示其他inputstream的逻辑连接。
* 它从一个有序的输入流集合开始,从第一个开始读取,直到到达文件末尾,
* 然后从第二个开始读取,以此类推,直到到达所包含的最后一个输入流的文件末尾。
*
* @author Author van Hoff
* @since JDK1.0
*/
public
class SequenceInputStream extends InputStream
基础属性 e,in,构造函数2个,nextStream方法
// 内部的Enumeration,可以不断调用它的nextElement方法
Enumeration<? extends InputStream> e;
// 当前读取的输入流
InputStream in;
/**
* 通过记住参数来初始化新创建的SequenceInputStream,
* 该参数必须是一个Enumeration,生成对象的运行时类型为InputStream。
* 枚举产生的输入流将被有序地读取,以提供要从这个SequenceInputStream读取的字节。
* 在枚举的每个输入流被耗尽后,将通过调用其close方法关闭它。
*
* @param e an enumeration of input streams.
* @see java.util.Enumeration
*/
public SequenceInputStream(Enumeration<? extends InputStream> e) {
this.e = e;
try {
// in为e的下一个流
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}
/**
* 通过记住两个参数(首先是s1,然后是s2)
* 来初始化一个新创建的SequenceInputStream,
* 以提供要从这个SequenceInputStream读取的字节。
*
* @param s1 the first input stream to read.
* @param s2 the second input stream to read.
*/
public SequenceInputStream(InputStream s1, InputStream s2) {
Vector<InputStream> v = new Vector<>(2);
v.addElement(s1);
v.addElement(s2);
e = v.elements();
// 创建一个e给它
try {
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}
/**
* 如果到达EOF,则继续在下一个流中读取。
*/
final void nextStream() throws IOException {
// 如果当前的流不为null,关闭当前的流
if (in != null) {
in.close();
}
// in变成e的下一个元素,如果没有,为null
if (e.hasMoreElements()) {
in = (InputStream) e.nextElement();
if (in == null)
throw new NullPointerException();
}
else in = null;
}
available,两个read,close方法
/**
* 返回可以从当前依赖的输入流读取(或跳过)的字节数的估计数,
* 而不会被当前依赖的输入流的方法的下一次调用阻塞。
* 下一个调用可能是同一个线程或另一个线程。
* 单个读取或跳过这许多字节不会阻塞,但可能读取或跳过更少的字节。
* 此方法只是调用当前依赖的输入流的available方法并返回结果。
*
* @return an estimate of the number of bytes that can be read (or
* skipped over) from the current underlying input stream
* without blocking or {@code 0} if this input stream
* has been closed by invoking its {@link #close()} method
* @exception IOException if an I/O error occurs.
*
* @since JDK1.1
*/
public int available() throws IOException {
if (in == null) {
return 0; // no way to signal EOF from available()
}
return in.available();
}
/**
* 从这个输入流中读取下一个字节的数据。
* 字节作为0到255之间的int类型返回。
* 如果由于到达流的末尾而没有可用的字节,则返回-1值。
* 此方法将一直阻塞,直到输入数据可用、检测到流的末尾或抛出异常为止。
* <p>
* 该方法尝试从当前子流中读取一个字符。
* 如果它到达流的末尾,它将调用当前子流的close方法并开始从下一个子流读取。
*
* @return the next byte of data, or <code>-1</code> if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
*/
public int read() throws IOException {
while (in != null) {
int c = in.read();
if (c != -1) {
return c;
}
nextStream();
}
// 不会返回-1,知道所有流都被读完
return -1;
}
/**
* 从这个输入中读取最多len字节的数据流到一个字节数组。
* 如果len不为零,该方法将阻塞,直到至少有1个字节的输入可用;
* 否则,什么字节都不读取并返回0。
* <p>
* SequenceInputStream的read方法尝试从当前子流中读取数据。
* 如果由于子流已经到达流的末尾而无法读取任何字符,
* 则调用当前子流的close方法,并从下一个子流开始读取。
*
* @param b the buffer into which the data is read.
* @param off the start offset in array <code>b</code>
* at which the data is written.
* @param len the maximum number of bytes read.
* @return int the number of bytes read.
* @exception NullPointerException If <code>b</code> is <code>null</code>.
* @exception IndexOutOfBoundsException If <code>off</code> is negative,
* <code>len</code> is negative, or <code>len</code> is greater than
* <code>b.length - off</code>
* @exception IOException if an I/O error occurs.
*/
public int read(byte b[], int off, int len) throws IOException {
if (in == null) {
return -1;
} else if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
do {
// 从当前的in读取,如果为0,则下一个流
int n = in.read(b, off, len);
if (n > 0) {
return n;
}
nextStream();
} while (in != null);
return -1;
}
/**
* 关闭该输入流并释放与该流关联的任何系统资源。
* 已关闭的SequenceInputStream不能执行输入操作,也不能重新打开。
* <p>
* 如果该流是从enumeration创建的,
* 则从枚举请求所有剩余的元素,并在close方法返回之前关闭。
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
do {
// 不断关闭当前流,并下一个
nextStream();
} while (in != null);
}