InputStream
が空かどうかを知りたいのですが、メソッドを使用していませんread()
。それを読まずにそれが空であるかどうかを知る方法はありますか?
8 に答える
いいえ、できません。InputStream
はリモートリソースで動作するように設計されているため、実際に読み取るまで、そこにあるかどうかはわかりません。
ただし、を使用java.io.PushbackInputStream
して、ストリームから何かがあるかどうかを確認し、ストリームを「プッシュバック」することができる場合があります(これは実際には機能しませんが、動作は次のようになります)。クライアントコード)。
私はあなたが探していると思いますinputstream.available()
。空かどうかはわかりませんが、データを読み取る必要があるかどうかを示すことができます。
PushbackInputStreamを使用するという提案に基づいて、ここに例示的な実装があります。
/**
* @author Lorber Sebastien <i>(lorber.sebastien@gmail.com)</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);
}
サポートマーク/リセットサポートを使用している場合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
このメソッドを使用して、呼び出した時点でavailable()
使用可能なデータがあるかどうかをストリームに問い合わせることができます。ただし、その関数がすべてのタイプの入力ストリームで機能することは保証されていません。つまり、への呼び出しが実際にブロックされるかどうかを判断するために使用することはできません。available()
read()
inputStreamReader.ready()を使用して調べてみませんか?
import java.io.InputStreamReader;
/// ...
InputStreamReader reader = new InputStreamReader(inputStream);
if (reader.ready()) {
// do something
}
// ...
読まなければ、これを行うことはできません。ただし、以下のような回避策を使用できます。
これを行うには、 mark( )メソッドとreset()メソッドを使用できます。
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を返します。
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;
}
}
}