Java I/O 12 - SequenceInputStream

  关于 java.io.SequenceInputStream 的部分笔记,SequenceInputStream中包含了多个输入流,多个输入流之间按照先后顺序依次通过read()方法提供新数据。本文演示代码段的执行环境基于JDK版本1.7

概述

  SequenceInputStream在其中维护了多个输入流,这些输入流按照先后顺序依次提供输入数据。如果当前输入流已经无法继续提供输入数据,那么就会取得下一个数据流,并从下一个输入流的read()方法中获取新的数据流。如果最后一个输入流的数据也已经读取完毕,那么就不会有新数据可以读取了。输入流的获取按照先后顺序依次进行。

继承关系

1
2
3
4
// SequenceInputStream
--java.lang.Object
--java.io.InputStream
--java.io.SequenceInputStream

实现接口

类名 实现接口
SequenceInputStream Closeable, AutoCloseable

ByteArrayInputStream

Constructor Summary

public SequenceInputStream(Enumeration<? extends InputStream> e)

1
2
3
4
5
6
7
8
9
public SequenceInputStream(Enumeration<? extends InputStream> e) {
this.e = e;
try {
nextStream();
} catch (IOException ex) {
// This should never happen
throw new Error("panic");
}
}

  入参是一个元素枚举类。通过遍历枚举类中的每一个元素(在SequenceInputStream为输入流),完成输入流的初始化操作。

public SequenceInputStream(InputStream s1, InputStream s2)

1
2
3
4
5
6
7
8
9
10
11
12
13
public SequenceInputStream(InputStream s1, InputStream s2) {
Vector 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");
}
}

  依次加入入参的两个输入流,遍历入参完成输入流的初始化操作。

部分方法

final void nextStream()

1
2
3
4
5
6
7
8
9
10
11
12
13
final void nextStream() throws IOException {
if (in != null) {
in.close();
}

if (e.hasMoreElements()) {
in = (InputStream) e.nextElement();
if (in == null)
throw new NullPointerException();
}
else in = null;

}

  获取下一个输入流。在初始化操作时会通过该方法获取第一个输入流。如果当前已有可用的输入流,且该输入流中已无可读取的数据,那么该方法会返回下一个输入流完成数据的读取操作。如果当前底层输入流不为空,那么关闭当前底层输入流并释放其占用的所有资源。

public int available()

1
2
3
4
5
6
public int available() throws IOException {
if(in == null) {
return 0; // no way to signal EOF from available()
}
return in.available();
}

  获取当前输入流中剩余可读取的数据长度。直接通过底层输入流中的available()方法获取计算结果。如果已无任何可用的输入流,那么返回0。

public int read()

1
2
3
4
5
6
7
8
9
10
11
public int read() throws IOException {
if (in == null) {
return -1;
}
int c = in.read();
if (c == -1) {
nextStream();
return read();
}
return c;
}

  尝试从当前底层输入流中读取一个字节的内容并返回。如果当前底层输入流中数据读取结束,那么在第7行代码中切换到下一个底层输入流,递归调用read()方法读取数据,直到最后一个底层输入流的内容也读取完毕。

public int read(byte b[], int off, int len)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
}

int n = in.read(b, off, len);
if (n <= 0) {
nextStream();
return read(b, off, len);
}
return n;
}

  尝试从当前底层输入流中读取长度为len个字节的内容并保存到数组b中。第2 ~ 10行代码完成方法入参的有效性校验,避免发生越界溢出。第12行代码从底层输入流中读取数据并保存到数组b中,如果未读取到任何数据,那么切换到下一个底层输入流,继续尝试读取数据。最后返回实际读取的数据长度。

public void close()

1
2
3
4
5
public void close() throws IOException {
do {
nextStream();
} while (in != null);
}

  关闭所有的底层输入流。

涉及基础知识点

  1. NIL

参考文献

  1. NIL



------------- End of this article, thanks! -------------


  版权声明:本文由Nathan R. Lee创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处。
  本文作者为 Nathan R. Lee
  本文标题为 Java I/O 12 - SequenceInputStream
  本文链接为 https://marcuseddie.github.io/2018/java-SequenceInputStream.html