Я хочу знать, является ли InputStream
пустым, но без использования метода read()
. Есть ли способ узнать, пусто ли оно, не читая с него?
Как я могу проверить, является ли InputStream пустым, не читая его?
Ответ 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;
}
}
}