Java - 重置 InputStream
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18793840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - Resetting InputStream
提问by iMineLink
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.
我正在处理一些 Java 代码,其中有一个 InputStream 我读了一次,然后我需要用相同的方法再次读取它。
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:
我找到了一个解决问题的hack-ish解决方案:
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?
这个解决方案是否会导致一些意想不到的行为?或者它会在它的愚蠢中工作?
采纳答案by kdgregory
As written, you have no guarantees, because mark()
is not required to report whether it was successful. To get a guarantee, you must first call markSupported(), and it must return true
.
正如所写,您没有任何保证,因为mark()
不需要报告它是否成功。要获得保证,您必须首先调用markSupported(),并且它必须返回true
。
Also as written, the specified read limit is very dangerous. If you happen to be using a stream that buffers in-memory, it will potentially allocate a 2GB buffer. On the other hand, if you happen to be using a FileInputStream
, you're fine.
同样如所写,指定的读取限制非常危险。如果您碰巧使用在内存中缓冲的流,它可能会分配一个 2GB 的缓冲区。另一方面,如果您碰巧使用了 a FileInputStream
,那就没问题了。
A better approach is to use a BufferedInputStream
with an explicit buffer.
更好的方法是将 aBufferedInputStream
与显式缓冲区一起使用。
回答by chrylis -cautiouslyoptimistic-
You can't do this reliably; some InputStream
s (such as ones connected to terminals or sockets) don't support mark
and reset
(see markSupported
). If you really have to traverse the data twice, you need to read it into your own buffer.
你不能可靠地做到这一点;某些InputStream
s(例如连接到终端或插座的那些)不支持mark
and reset
(请参阅markSupported
)。如果你真的必须遍历数据两次,你需要将它读入你自己的缓冲区。
回答by stan
It depends on the InputStream implementation. You can also think whether it will be better if you use byte[]. The easiest way is to use Apache commons-io:
这取决于 InputStream 实现。也可以想想用byte[]会不会更好。最简单的方法是使用 Apache commons-io:
byte[] bytes = IOUtils.toByteArray(inputSream);
回答by Ravi Thapliyal
Instead of trying to reset the InputStream
load it into a buffer like a StringBuilder
or if it's a binary data stream a ByteArrayOutputStream
. You can then process the buffer within the method as many times as you want.
而不是尝试将其重置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();
回答by androidguy
For me, the easiest solution was to pass the object from which the InputStream could be obtained, and just obtain it again. In my case, it was from a ContentResolver
.
对我来说,最简单的解决方案是传递可以从中获取 InputStream 的对象,然后再次获取它。就我而言,它来自ContentResolver
.