How can I check if an InputStream is empty without reading from it?

前端 未结 8 933
无人及你
无人及你 2020-12-08 18:10

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?

8条回答
  •  粉色の甜心
    2020-12-08 18:47

    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);
      }
    

提交回复
热议问题