20

I'm dealing with some Java code in which there's an InputStream that I read one time and then I need to read it once again in the same method.

The problem is that I need to reset it's position to the start in order to read it twice.

I've found a hack-ish solution to the problem:

is.mark(Integer.MAX_VALUE);

//Read the InputStream is fully
// { ... }

try
{
    is.reset();
}
catch (IOException e)
{
    e.printStackTrace();
}

Does this solution lead to some unespected behaviours? Or it will work in it's dumbness?

4

5 回答 5

12

正如所写,您没有任何保证,因为mark()不需要报告它是否成功。要获得保证,您必须首先调用markSupported(),并且它必须返回true

同样如所写,指定的读取限制非常危险。如果你碰巧使用了一个在内存中缓冲的流,它可能会分配一个 2GB 的缓冲区。另一方面,如果你碰巧在使用 a FileInputStream,那你很好。

更好的方法是将 aBufferedInputStream与显式缓冲区一起使用。

于 2013-09-13T19:39:25.107 回答
3

这取决于 InputStream 的实现。也可以考虑用byte[]会不会更好。最简单的方法是使用 Apache commons-io

byte[] bytes = IOUtils.toByteArray(inputSream);
于 2013-09-13T19:38:44.363 回答
2

你不能可靠地做到这一点。有些InputStreams(例如连接到终端或插座的)不支持markand reset(请参阅markSupported)。如果你真的要遍历数据两次,你需要把它读入你自己的缓冲区。

于 2013-09-13T19:37:47.183 回答
1

而不是尝试将InputStream加载重置到像 a 这样的缓冲区中,StringBuilder或者如果它是二进制数据流 a 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();
于 2013-09-13T19:39:12.147 回答
1

对我来说,最简单的解决方案是传递可以从中获取 InputStream 的对象,然后再次获取它。就我而言,它来自ContentResolver.

于 2017-05-14T08:10:43.347 回答