如何在不读取的情况下检查InputStream是否为空?

时间:2009-10-06 08:32:08

标签: java inputstream

我想知道InputStream是否为空,但不使用方法read()。有没有办法知道它是否是空的而没有从中读取?

8 个答案:

答案 0 :(得分:55)

不,你不能。 InputStream旨在使用远程资源,因此在您实际读取它之前,您无法知道它是否存在。

然而,您可以使用java.io.PushbackInputStream,它允许您从流中读取以查看是否存在某些内容,然后将其“向后推”到流中(这不是它真正起作用的方式) ,但这就是它对客户端代码的行为方式。)

答案 1 :(得分:37)

我认为您正在寻找inputstream.available()。它不会告诉您它是否为空,但它可以指示您是否有数据被读取。

答案 2 :(得分:9)

根据使用PushbackInputStream的建议,你会在这里找到一个例子:

/**
 * @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);
    }
  }

}

以下是一些通过测试:

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

答案 3 :(得分:4)

您可以使用available()方法向流询问在您调用时是否有任何可用的数据。但是,不保证该功能适用​​于所有类型的输入流。这意味着您无法使用available()来确定对read()的调用是否会实际阻止。

答案 4 :(得分:4)

如果您使用的InputStream支持标记/重置支持,您还可以尝试读取流的第一个字节,然后将其重置为原始位置:

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

如果您不控制您正在使用的InputStream类型,可以使用markSupported()方法检查标记/重置是否适用于流,并回退到{ {1}}方法或available()方法。

答案 5 :(得分:1)

如何使用inputStreamReader.ready()查找?

import java.io.InputStreamReader;

/// ...

InputStreamReader reader = new InputStreamReader(inputStream);
if (reader.ready()) {
    // do something
}

// ...

答案 6 :(得分:0)

没有阅读,您将无法执行此操作。但是您可以使用以下解决方法。

您可以使用mark()reset()方法来做到这一点。

mark(int readlimit)方法标记此输入流中的当前位置。

reset()方法将此流重新定位到在此输入流上最后一次调用mark方法的位置。

在使用标记和重置之前,需要测试要读取的输入流是否支持这些操作。您可以使用markSupported来做到这一点。

mark方法接受一个限制(整数),该限制表示要预先读取的最大字节数。如果您阅读的内容超出此限制,则无法返回此标记。

要在此用例中应用此功能,我们需要将该位置标记为0,然后读取输入流。之后,我们需要重置输入流,然后输入流将还原为原始流。

    if (inputStream.markSupported()) {
          inputStream.mark(0);
          if (inputStream.read() != -1) {
               inputStream.reset();
          } else {
               //Inputstream is empty
          }
    }

如果输入流为空,则read()方法将返回-1。

答案 7 :(得分:-3)

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