Ben
Ben

Reputation: 4299

Problems reading multiple files line by line when using SequenceInputStream

I'm reading multiple files line-by line, and found SequenceInputStream handy. Here's how I use it:

try (
    InputStream in = new SequenceInputStream(new FileInputStream(file1),new FileInputStream(file2));
    Scanner reader = new Scanner(source)) {
    while ( reader.hasNext ()) {
        System.out.println(reader.nextLine());
    }
}

However it has a peculiar problem. Lets say that:

File1

a
b

File2

c
d

Then the executed code will output:

a
bc
d

It seems that it does not distinguish between lines from separate files, is there a way to fix this? (yes, I really need to merge multiple InputStreams into one)

Upvotes: 0

Views: 1094

Answers (3)

Ben
Ben

Reputation: 4299

As other answers pointed out, I could create my own SequenceInputStream implementation, or wrap each stream into FilterInputStream. However I think I found a simpler solution: just insert streams that provide endline between my file streams.

InputStream in = new SequenceInputStream(
    new FileInputStream(file1),
    new SequenceInputStream(
        new ByteArrayInputStream("\n".getBytes()), // gives an endline between the provided files
        new FileInputStream(file2)));

Upvotes: 1

Andreas
Andreas

Reputation: 159165

If you are sequencing multiple streams and want to ensure that each end in a line separator, wrap each stream in a FilterInputStream that returns an extra line separator at the end, if not in the filtered stream.

Upvotes: 1

dkatzel
dkatzel

Reputation: 31658

SequenceInputStream hides the EOF characters from the all the wrapped files except for the last file:

 public int read() throws IOException {
    if (in == null) {
        return -1;
    }
    int c = in.read();
    if (c == -1) {
        nextStream();
        return read();
    }
    return c;
}

So if the files don't end with a new line, then the first line of file2 will get appended to the last line of file1.

If you really need to use a single inputStream and you need to have separate lines to separate each file, you probably have to write your own InputStream implementation that checks that there is a newline character as the last line of the file and if not, inserts one as part the read() method.

Upvotes: 2

Related Questions