ConcatClosingInputStream extends InputStream { @Override public int read() throws IOException { if (closed) return -1; if (current == null) { return safeCloseAndThrow(new IOException("cannot read from null Stream")); } int read; try { read = current.read(); } catch (IOException e) { return safeCloseAndThrow(e); } if (read >= 0) return read; else { try { current.close(); } catch (IOException e) { return safeCloseAndThrow(e); } if (streams.hasNext()) { current = streams.next(); return read(); } else { closed = true; return -1; } } } ConcatClosingInputStream(Iterator<InputStream> streams); @Override int read(); @Override void close();  }
@Test public void testReadIsEmptyForEmptyIterator() throws Exception { ImmutableList<InputStream> inputStreams = ImmutableList.of(); ConcatClosingInputStream concatClosingInputStream = new ConcatClosingInputStream(inputStreams.iterator()); assertThat(concatClosingInputStream.read(), is(-1)); assertThat(concatClosingInputStream.read(), is(-1)); assertThat(concatClosingInputStream.read(), is(-1)); }
@Test public void testReadCorrectlyProxiesForASingle() throws Exception { InputStream a = mock(InputStream.class); when(a.read()).thenReturn(1, 2, -1); ImmutableList<InputStream> inputStreams = ImmutableList.of(a); ConcatClosingInputStream concatClosingInputStream = new ConcatClosingInputStream(inputStreams.iterator()); assertThat(concatClosingInputStream.read(), is(1)); assertThat(concatClosingInputStream.read(), is(2)); assertThat(concatClosingInputStream.read(), is(-1)); assertThat(concatClosingInputStream.read(), is(-1)); assertThat(concatClosingInputStream.read(), is(-1)); }
@Test public void testThrowingOnNullStreams() throws IOException { @SuppressWarnings("unchecked") Iterator<InputStream> inputStreams = mock(Iterator.class); when(inputStreams.hasNext()).thenReturn(true, false); when(inputStreams.next()).thenReturn(null); ConcatClosingInputStream concatClosingInputStream = new ConcatClosingInputStream(inputStreams); expectedException.expect(IOException.class); expectedException.expectMessage("cannot read from null Stream"); @SuppressWarnings("unused") int unused = concatClosingInputStream.read(); fail("expected exception"); }