Подтвердить что ты не робот

Как я могу проверить, является ли InputStream пустым, не читая его?

Я хочу знать, является ли InputStream пустым, но без использования метода read(). Есть ли способ узнать, пусто ли оно, не читая с него?

4b9b3361

Ответ 1

Я думаю, что вы ищете inputstream.available(). Он не говорит вам, является ли его пустым, но он может дать вам указание о том, следует ли читать данные или нет.

Ответ 2

Нет, вы не можете. InputStream предназначен для работы с удаленными ресурсами, поэтому вы не можете знать, будет ли он там, пока вы на самом деле не прочитаете его.

Возможно, вы сможете использовать java.io.PushbackInputStream, который позволяет вам читать из потока, чтобы увидеть, есть ли там что-то, а затем "оттолкнуть его" вверх по потоку (что не так, как это работает, но что он ведет себя к клиентскому коду).

Ответ 3

Основываясь на предположении использования 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);
  }

Ответ 4

Вы можете использовать метод available(), чтобы спросить поток, есть ли какие-либо данные в момент его вызова. Однако эта функция не гарантирует работу всех типов входных потоков. Это означает, что вы не можете использовать available(), чтобы определить, действительно ли будет блокироваться вызов read().

Ответ 5

Если поддержка InputStream поддерживает поддержку mark/reset, вы также можете попытаться прочитать первый байт потока, а затем reset в исходное положение:

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

Если вы не контролируете, какой тип InputStream вы используете, вы можете использовать метод markSupported(), чтобы проверить, будет ли mark/reset работать с потоком, и вернуться к available() метод или метод java.io.PushbackInputStream в противном случае.

Ответ 6

Как насчет использования inputStreamReader.ready(), чтобы узнать?

import java.io.InputStreamReader;

/// ...

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

// ...

Ответ 7

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