SequenceInputStream的源码和Vector.class的一些函数说明(windows操作系统,JDK8)
SequenceInputStream.class的源码,如下所示:
package java.io;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;
public
class SequenceInputStream extends InputStream {
//顺序(序列化)装载多个被装饰输入Stream的集合,一般是Vector实例
Enumeration<? extends InputStream> e;
InputStream in;//顺序(序列化)装载多个被装饰输入Stream的集合中当前正在被SequenceInputStream 对象使用的被装饰的输入Stream
//构造函数,传入一个顺序(序列化)装载多个被装饰输入Stream的集合
public SequenceInputStream(Enumeration<? extends InputStream> e) {
this.e = e;
try {
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}
//构造函数,可以将2个被装饰的输入Stream放入到集合中
public SequenceInputStream(InputStream s1, InputStream s2) {
Vector<InputStream> v = new Vector<>(2);
v.addElement(s1);
v.addElement(s2);
e = v.elements();
try {
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}
//获取集合中下一个被装饰的输入Stream
final void nextStream() throws IOException {
if (in != null) {
in.close();//先关闭当前被装饰的输入Stream
}
if (e.hasMoreElements()) {//如果集合中还有被装饰的输入Stream
in = (InputStream) e.nextElement();//获取集合中下一个被装饰的输入Stream
if (in == null)
throw new NullPointerException();//如果集合中下一个被装饰的输入Stream为null,抛出一个NullPointerException
}
else in = null;//如果集合中没有了被装饰的输入Stream,将当前正在使用的被装饰的输入Stream置为null
}
//判断当前正在使用的被装饰的输入Stream是否还有可以读取的字节数据
public int available() throws IOException {
if (in == null) {
return 0; // no way to signal EOF from available()
}
return in.available();
}
//从SequenceInputStream 对象的集合(该集合放着多个被装饰的输入Stream)中读取1个字节
public int read() throws IOException {
while (in != null) {//如果in!=null,则说明当前这个SequenceInputStream 对象的集合中还有被装饰的输入Stream没有关闭
int c = in.read();//从当前正在使用的被装饰的被装饰输入Stream中读取1个字节
if (c != -1) {//c != -1说明从当前正在使用的被装饰输入Stream中读取到了字节
return c;//返回读取到的这个字节
}
nextStream();//如果c==-1说明当前正在使用的被装饰输入Stream中字节(byte)数据已经读完,获取SequenceInputStream 对象的集合中下一个被装饰的输入Stream
}
return -1;//如果SequenceInputStream 对象的集合中所有被装饰的输入Stream中的字节(byte)数据都已经读完,返回-1
}
//从SequenceInputStream 对象的集合(该集合放着多个被装饰的输入Stream)中读取len个字节,放入到byte[]数组b的[off,off+len)(左闭右开,不包括off+len)索引位置
public int read(byte b[], int off, int len) throws IOException {
if (in == null) {//如果in==null,则说明当前这个SequenceInputStream 对象的集合中所有被装饰的输入Stream都已经关闭
return -1;
} else if (b == null) {
throw new NullPointerException();//如果byte[]数组b==null,抛出一个NullPointerException
} else if (off < 0 || len < 0 || len > b.length - off) {//相当于off + len > b.length(源码中这样写代码的好处我没看出来)
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;//要从SequenceInputStream 对象的集合(该集合放着至少2个被装饰的输入Stream)中读取的len个字节==0时,返回0
}
do {
int n = in.read(b, off, len);//从当前正在使用的被装饰的输入Stream中读取len个字节,放入到byte[]数组b的[off,off+len)(左闭右开,不包括off+len)索引位置
if (n > 0) {
return n;//只要能从当前正在使用的被装饰的输入Stream中读取到字节,则返回读取的数量
}
nextStream();//此时n==-1,说明当前正在使用的被装饰的输入Stream中字节(byte)数据已经读完,获取SequenceInputStream 对象的集合中下一个被装饰的输入Stream
} while (in != null);//SequenceInputStream 对象的集合中下一个被装饰的输入Stream为null时,跳出循环,返回-1
return -1;
}
//顺序关闭SequenceInputStream 对象的集合中所有被装饰的输入Stream
public void close() throws IOException {
do {
nextStream();
} while (in != null);
}
}
1.1、SequenceInputStream的read()函数和nextStream()函数
package java.io;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;
public
class SequenceInputStream extends InputStream {
...省略部分代码...
//顺序(序列化)存储多个被装饰的输入Stream的集合,一般是Vector实例
Enumeration<? extends InputStream> e;
InputStream in;//顺序(序列化)装载多个被装饰输入Stream的集合中当前正在被SequenceInputStream 对象使用的被装饰的输入Stream
//获取集合中下一个被装饰的输入Stream
final void nextStream() throws IOException {
if (in != null) {
in.close();//先关闭当前被装饰的输入Stream
}
if (e.hasMoreElements()) {//如果集合中还有被装饰的输入Stream
in = (InputStream) e.nextElement();//获取集合中下一个被装饰的输入Stream
if (in == null)
throw new NullPointerException();//如果集合中下一个被装饰的输入Stream为null,抛出一个NullPointerException
}
else in = null;//如果集合中没有了被装饰的输入Stream,将当前正在使用的被装饰的输入Stream置为null
}
//从SequenceInputStream 对象的集合(该集合放着多个被装饰的输入Stream)中读取1个字节
public int read() throws IOException {
while (in != null) {//如果in!=null,则说明当前这个SequenceInputStream 对象的集合中还有被装饰的输入Stream没有关闭
int c = in.read();//从当前正在使用的被装饰的被装饰输入Stream中读取1个字节
if (c != -1) {//c != -1说明从当前正在使用的被装饰输入Stream中读取到了字节
return c;//返回读取到的这个字节
}
nextStream();//如果c==-1说明当前正在使用的被装饰输入Stream中字节(byte)数据已经读完,获取SequenceInputStream 对象的集合中下一个被装饰的输入Stream
}
return -1;//如果SequenceInputStream 对象的集合中所有被装饰的输入Stream中的字节(byte)数据都已经读完,返回-1
}
...省略部分代码...
}
如果使用者用的是2个被装饰的输入Stream(此处为FileInputStream),构造的SequenceInputStream的对象,如下所示(伪代码):
is1 = new FileInputStream("D:\\data1.txt");
is2 = new FileInputStream("D:\\data2.txt");
sequenceInputStream = new SequenceInputStream(is1, is2);
那么,SequenceInputStream对象中Vector集合的容量是2,如果此时执行SequenceInputStream.class::read()函数。
//伪代码
int readByte = -1;
while ((readByte = sequenceInputStream.read()) != -1) {
System.out.print((char) readByte);
}
过程如下(假设2个被装饰的输入Stream(此处为FileInputStream)中的字节数据如下):

①、先执行第1个被装饰的输入Stream(也是Vector集合的第1个元素)的read()函数,直到该函数返回-1,如下所示:


②、关闭第1个被装饰的输入Stream(也是Vector集合的第1个元素),再执行第2个被装饰的输入Stream(也是Vector集合的第2个元素)的read()函数,直到该函数返回-1,如下所示:


1.1.1、使用举例
下面这个例子就恰当的使用SequenceInputStream的read()函数;
-
我的windows操作系统的D盘根目录下有2个txt文件,一个是data1.txt,另一个是data2.txt文件,这2个文件中总共有30个字节,如下所示:


-
使用者可以用一个SequenceInputStream对象装饰2个被装饰的输入Stream(此处为FileInputStream),如下代码所示:
package com.chelong.StreamAndReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
public class SequenceInputStreamTest {
public static void main(String[] args) {
InputStream is1 = null;
InputStream is2 = null;
SequenceInputStream sequenceInputStream = null;
try {
is1 = new FileInputStream("D:\\data1.txt");
is2 = new FileInputStream("D:\\data2.txt");
sequenceInputStream = new SequenceInputStream(is1, is2);
int readByte = -1;
while ((readByte = sequenceInputStream.read()) != -1) {
System.out.print((char) readByte);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//此处省略关闭所有的Stream的代码
}
}
}
程序运行结果,如下所示:

1.2、SequenceInputStream的read(byte b[], int off, int len)函数和nextStream()函数
package java.io;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;
public
class SequenceInputStream extends InputStream {
...省略部分代码...
//顺序(序列化)装载多个被装饰输入Stream的集合,一般是Vector实例
Enumeration<? extends InputStream> e;
InputStream in;//顺序(序列化)装载多个被装饰输入Stream的集合中当前正在被SequenceInputStream 对象使用的被装饰的输入Stream
//获取集合中下一个被装饰的输入Stream
final void nextStream() throws IOException {
if (in != null) {
in.close();//先关闭当前被装饰的输入Stream
}
if (e.hasMoreElements()) {//如果集合中还有被装饰的输入Stream
in = (InputStream) e.nextElement();//获取集合中下一个被装饰的输入Stream
if (in == null)
throw new NullPointerException();//如果集合中下一个被装饰的输入Stream为null,抛出一个NullPointerException
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)