Java 如何在不读取的情况下检查 InputStream 是否为空?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1524299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I check if an InputStream is empty without reading from it?
提问by Jenny Smith
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?
我想知道 anInputStream
是否为空,但不使用方法read()
。有没有办法在不阅读的情况下知道它是否为空?
采纳答案by vpram86
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.
我想你正在寻找inputstream.available()
。它不会告诉您它是否为空,但它可以指示您是否可以读取数据。
回答by skaffman
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.
不,你不能。InputStream
旨在处理远程资源,因此在您实际读取它之前,您无法知道它是否存在。
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).
java.io.PushbackInputStream
但是,您可以使用 a ,它允许您从流中读取以查看那里是否有内容,然后将其“推回”流(这不是它真正的工作方式,但这就是它的行为方式)客户代码)。
回答by Greg Hewgill
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.
您可以使用该available()
方法询问流在您调用它的那一刻是否有任何数据可用。但是,不能保证该函数适用于所有类型的输入流。这意味着您不能使用available()
来确定调用是否read()
会实际阻塞。
回答by Henning
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:
如果InputStream
您使用的支持标记/重置支持,您还可以尝试读取流的第一个字节,然后将其重置到其原始位置:
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.
如果您不控制InputStream
您使用的是哪种类型,您可以使用该markSupported()
方法来检查标记/重置是否适用于流,并回退到该available()
方法或其他java.io.PushbackInputStream
方法。
回答by shaolang
How about using inputStreamReader.ready()to find out?
如何使用inputStreamReader.ready()找出?
import java.io.InputStreamReader;
/// ...
InputStreamReader reader = new InputStreamReader(inputStream);
if (reader.ready()) {
// do something
}
// ...
回答by Sebastien Lorber
Based on the suggestion of using the PushbackInputStream, you'll find an exemple implementation here:
根据使用 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);
}
}
}
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);
}
回答by omer
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;
}
}
}
回答by CodeFrc
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.
mark(int readlimit) 方法标记此输入流中的当前位置。
reset() method repositions this stream to the position at the time the mark method was last called on this input stream.
reset() 方法将此流重新定位到上次在此输入流上调用 mark 方法时的位置。
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.
在您可以使用标记和重置之前,您需要测试您正在读取的输入流是否支持这些操作。您可以使用 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.
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.
要将此功能应用于此用例,我们需要将位置标记为 0,然后读取输入流。之后我们需要重置输入流,输入流将恢复为原始流。
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.
如果输入流为空,则 read() 方法将返回 -1。