I want to know if an InputStream
is empty, but without using the method read()
. Is there a way to know if it\'s empty without reading from it?
Based on the suggestion of using the PushbackInputStream, you'll find an exemple implementation here:
/**
* @author Lorber Sebastien (lorber.sebastien@gmail.com)
*/
public class NonEmptyInputStream extends FilterInputStream {
/**
* Once this stream has been created, do not consume the original InputStream
* because there will be one missing byte...
* @param originalInputStream
* @throws IOException
* @throws EmptyInputStreamException
*/
public NonEmptyInputStream(InputStream originalInputStream) throws IOException, EmptyInputStreamException {
super( checkStreamIsNotEmpty(originalInputStream) );
}
/**
* Permits to check the InputStream is empty or not
* Please note that only the returned InputStream must be consummed.
*
* see:
* http://stackoverflow.com/questions/1524299/how-can-i-check-if-an-inputstream-is-empty-without-reading-from-it
*
* @param inputStream
* @return
*/
private static InputStream checkStreamIsNotEmpty(InputStream inputStream) throws IOException, EmptyInputStreamException {
Preconditions.checkArgument(inputStream != null,"The InputStream is mandatory");
PushbackInputStream pushbackInputStream = new PushbackInputStream(inputStream);
int b;
b = pushbackInputStream.read();
if ( b == -1 ) {
throw new EmptyInputStreamException("No byte can be read from stream " + inputStream);
}
pushbackInputStream.unread(b);
return pushbackInputStream;
}
public static class EmptyInputStreamException extends RuntimeException {
public EmptyInputStreamException(String message) {
super(message);
}
}
}
And here are some passing tests:
@Test(expected = EmptyInputStreamException.class)
public void test_check_empty_input_stream_raises_exception_for_empty_stream() throws IOException {
InputStream emptyStream = new ByteArrayInputStream(new byte[0]);
new NonEmptyInputStream(emptyStream);
}
@Test
public void test_check_empty_input_stream_ok_for_non_empty_stream_and_returned_stream_can_be_consummed_fully() throws IOException {
String streamContent = "HELLooooô wörld";
InputStream inputStream = IOUtils.toInputStream(streamContent, StandardCharsets.UTF_8);
inputStream = new NonEmptyInputStream(inputStream);
assertThat(IOUtils.toString(inputStream,StandardCharsets.UTF_8)).isEqualTo(streamContent);
}