[英]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
(例如连接到终端或套接字的那些)不支持mark
和reset
(请参阅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.