繁体   English   中英

Java - 重置InputStream

[英]Java - Resetting InputStream

我正在处理一些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 (例如连接到终端或套接字的那些)不支持markreset (请参阅markSupported )。 如果你真的必须遍历数据两次,你需要将它读入你自己的缓冲区。

它取决于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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM