Java - 重置输入流



我正在处理一些Java代码,其中有一个InputStream,我读取了一次,然后我需要以相同的方法再次读取它。

问题是我需要将其位置重置为开头才能读取两次。

我找到了解决这个问题的黑客式解决方案:

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 实现。你也可以考虑如果使用byte[]是否会更好。最简单的方法是使用 Apache commons-io:

byte[] bytes = IOUtils.toByteArray(inputSream);

您无法可靠地执行此操作;某些InputStream(例如连接到终端或插座的)不支持markreset(请参阅markSupported)。如果确实必须遍历数据两次,则需要将其读入自己的缓冲区。

与其尝试重置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();

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

相关内容

  • 没有找到相关文章

最新更新