web-dev-qa-db-ja.com

InputStreamを読み取らずにInputStreamが空かどうかを確認するにはどうすればよいですか?

InputStreamが空かどうかを知りたいのですが、メソッドread()を使用しません。読み取らずに空かどうかを知る方法はありますか?

52
Jenny Smith

inputstream.available() を探していると思います。空かどうかはわかりませんが、データが読み取られるかどうかを示すことができます。

37
vpram86

いいえ、できません。 InputStreamはリモートリソースで動作するように設計されているので、実際に読み取るまでそこにあるかどうかはわかりません。

ただし、Java.io.PushbackInputStreamを使用できる場合があります。これにより、ストリームから読み取り、そこに何かがあるかどうかを確認し、ストリームを「プッシュバック」することができます(実際には機能しませんが、クライアントコードに対する動作方法)。

56
skaffman

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

available() メソッドを使用して、ストリームに利用可能なデータがあるかどうかを尋ねることができます、呼び出した瞬間に。ただし、その機能がすべてのタイプの入力ストリームで機能することは保証されていません。つまり、available()を使用してread()の呼び出しが実際にブロックされるかどうかを判断できないことを意味します。

4
Greg Hewgill

使用している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_メソッド。

4
Henning

inputStreamReader.ready() を使用して調べる方法は?

import Java.io.InputStreamReader;

/// ...

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

// ...
1
shaolang