私はいくつかのJavaコードを扱っています。このコードでは、一度読み取ったInputStreamがあり、同じメソッドでもう一度読み取る必要があります。
問題は、2回読むために、その位置を最初にリセットする必要があることです。
私は問題のハックっぽい解決策を見つけました:
is.mark(Integer.MAX_VALUE);
//Read the InputStream is fully
// { ... }
try
{
is.reset();
}
catch (IOException e)
{
e.printStackTrace();
}
この解決策は、疑わしい行動につながるのですか?それとも、それは愚かさで機能しますか?
書かれているとおり、mark()
は成功したかどうかを報告する必要がないため、保証はありません。保証を得るには、最初に markSupported() を呼び出し、true
を返す必要があります。
また、書かれているように、指定された読み取り制限は非常に危険です。メモリ内でバッファリングするストリームを使用している場合、2GBのバッファが割り当てられる可能性があります。一方、FileInputStream
を使用している場合は問題ありません。
より適切な方法は、明示的なバッファでBufferedInputStream
を使用することです。
これを確実に行うことはできません。一部のInputStream
s(端末やソケットに接続されているものなど)はmark
およびreset
をサポートしていません( markSupported
を参照) 。データを2回トラバースする必要がある場合は、独自のバッファーに読み込む必要があります。
これは、InputStreamの実装によって異なります。また、byte []を使用した方が良いかどうかを考えることもできます。最も簡単な方法は、Apache commons-io を使用することです。
byte[] bytes = IOUtils.toByteArray(inputSream);
InputStream
をリセットしようとする代わりに、StringBuilder
のようにバッファにロードするか、バイナリデータストリームの場合はByteArrayOutputStream
をロードします。その後、メソッド内のバッファを何度でも処理できます。
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
byte[] buff = new byte[1024];
while ((read = inStream.read(buff)) != -1) {
bos.write(buff, 0, read);
}
byte[] streamData = bos.toByteArray();
私にとって、最も簡単な解決策は、InputStreamを取得できるオブジェクトを渡して、再度取得することでした。私の場合、それはContentResolver
からのものでした。