How to use SequenceInputStream?

Tags: ,



🍳Background

  • 1.I was learning the basic grammar of input and output in java.
  • 2.But I found that the SequenceInputStream worked strangely.

Code

package book1.chapter10;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.SequenceInputStream;

public class Test1 {
    public static void main(String[] args) throws IOException {
        byte[] box = new byte[50];
        FileInputStream fin1 = new FileInputStream("D:/Workspace/Java/src/book1/chapter10/data1.txt");
        FileInputStream fin2 = new FileInputStream("D:/Workspace/Java/src/book1/chapter10/data2.txt");
        //fin1's content:"learn!".
        //fin2's content:"java!".
        SequenceInputStream finAll = new SequenceInputStream(fin1,fin2);
        System.out.println("available:" + finAll.available());
        //try read ten:
        finAll.read(box,0,10);
        System.out.println("available:" + finAll.available());
        //try read one more:
        int temp = fin1.read();
        System.out.println("available:" + finAll.available());
        //outcome:
        for(byte x: box) {
            if (x != 0) System.out.print(x +",");
        }
        System.out.println(temp == -1);
        //try read ten again!
        byte[] newBox = new byte[50];
        finAll.read(newBox,0,10);
        System.out.println("available:" + finAll.available());
        //outcome:
        for(byte x: newBox) {
            if (x != 0) System.out.print(x +",");
        }
    }
}

outcome

available:6
available:0
available:0
108,101,97,114,110,33,true
available:0
106,97,118,97,33,

🔑Question

  • 1.Why did the method(read) stop when meet EOF?
  • 2.How to read the next Stream?

Answer

Why did the method(read) stop when meet EOF?

You might be expecting it to read “learn!java” on the first call to read, but that’s not what read is documented to do (emphasis mine):

The read method of SequenceInputStream tries to read the data from the current substream. If it fails to read any characters because the substream has reached the end of the stream, it calls the close method of the current substream and begins reading from the next substream.

“Current substream” is the keyword here. It doesn’t try to read data from any other substream, but the current one. Just after you created the SequenceInputStream, the current substream is the first one – fin1. The first call to read will hence read from fin1, and you won’t get anything from fin2.

The parameterless read also says something similar.

This method tries to read one character from the current substream. If it reaches the end of the stream, it calls the close method of the current substream and begins reading from the next substream.

How to read the next Stream?

Well, according to the second half of each quote, the SequenceInputStream reads from the next stream when it can’t read anything from the current stream anymore. In your code, the first call to finAll.read read everything in fin1, so the second call can’t read anything from fin1 anymore, so it starts reading from fin2.

If you want the data that is read to be in the same byte array, just change the offset parameter to the number of bytes read:

int bytesRead = finAll.read(box, 0, 10);
finAll.read(box, bytesRead, 10 - bytesRead);


Source: stackoverflow