如何在不读取输入流的情况下检查它是否为空?

发布于 2024-08-07 00:47:00 字数 91 浏览 2 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

凡尘雨 2024-08-14 00:47:00

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

但是,您也许可以使用 java.io.PushbackInputStream,它允许您从流中读取内容以查看其中是否有内容,然后将其“推回”流中(这不是它实际上是如何工作的,但这就是它对客户端代码的行为方式)。

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).

寄风 2024-08-14 00:47:00

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

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.

无风消散 2024-08-14 00:47:00

根据使用 PushbackInputStream 的建议,您将在此处找到示例实现:

/**
 * @author Lorber Sebastien <i>([email protected])</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);
  }

Based on the suggestion of using the PushbackInputStream, you'll find an exemple implementation here:

/**
 * @author Lorber Sebastien <i>([email protected])</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);
  }
耳钉梦 2024-08-14 00:47:00

如果您使用的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() 方法来检查标记/重置是否适用于流,然后回退到 available( ) 方法或 java.io.PushbackInputStream 方法,否则。

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.

悲歌长辞 2024-08-14 00:47:00

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

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.

落日海湾 2024-08-14 00:47:00

如何使用 inputStreamReader.ready()找出答案?

import java.io.InputStreamReader;

/// ...

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

// ...

How about using inputStreamReader.ready() to find out?

import java.io.InputStreamReader;

/// ...

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

// ...
ˉ厌 2024-08-14 00:47:00

不阅读你就无法做到这一点。但您可以使用如下解决方法。

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

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。

Without reading you can't do this. But you can use a work around like below.

You can use mark() and reset() methods to do this.

mark(int readlimit) method marks the current position in this input stream.

reset() method repositions this stream to the position at the time the mark method was last called on this input stream.

Before you can use the mark and reset, you need to test out whether these operations are supported on the inputstream you’re reading off. You can do that with markSupported.

The mark method accepts an limit (integer), which denotes the maximum number of bytes that are to be read ahead. If you read more than this limit, you cannot return to this mark.

To apply this functionalities for this use case, we need to mark the position as 0 and then read the input stream. There after we need to reset the input stream and the input stream will be reverted to the original one.

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

Here if the input stream is empty then read() method will return -1.

原谅过去的我 2024-08-14 00:47:00
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;
        }
    }
}
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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文