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

前端 未结 8 870
无人及你
无人及你 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 <i>(lorber.sebastien@gmail.com)</i>
     */
    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);
      }
    
    0 讨论(0)
  • 2020-12-08 18:48
    public void run() {
        byte[] buffer = new byte[256];  
        int bytes;                      
    
        while (true) {
            try {
                bytes = mmInStream.read(buffer);
                mHandler.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 18:50

    I think you are looking for inputstream.available(). It does not tell you whether its empty but it can give you an indication as to whether data is there to be read or not.

    0 讨论(0)
  • 2020-12-08 18:56

    You can use the available() method to ask the stream whether there is any data available at the moment you call it. However, that function isn't guaranteed to work on all types of input streams. That means that you can't use available() to determine whether a call to read() will actually block or not.

    0 讨论(0)
  • 2020-12-08 18:57

    No, you can't. InputStream is designed to work with remote resources, so you can't know if it's there until you actually read from it.

    You may be able to use a java.io.PushbackInputStream, however, which allows you to read from the stream to see if there's something there, and then "push it back" up the stream (that's not how it really works, but that's the way it behaves to client code).

    0 讨论(0)
  • 2020-12-08 18:59

    If the InputStream you're using supports mark/reset support, you could also attempt to read the first byte of the stream and then reset it to its original position:

    input.mark(1);
    final int bytesRead = input.read(new byte[1]);
    input.reset();
    if (bytesRead != -1) {
        //stream not empty
    } else {
        //stream empty
    } 
    

    If you don't control what kind of InputStream you're using, you can use the markSupported() method to check whether mark/reset will work on the stream, and fall back to the available() method or the java.io.PushbackInputStream method otherwise.

    0 讨论(0)
提交回复
热议问题