我有一个InputStream,我将它传递给一个方法进行一些处理。我将在其他方法中使用相同的InputStream,但是在第一次处理之后,InputStream似乎在该方法中是封闭的。
我如何克隆要发送给关闭他的方法的InputStream?还有其他的解决方案吗?
编辑:关闭InputStream的方法是库中的外部方法。我不能控制关闭与否。
private String getContent(HttpURLConnection con) {
InputStream content = null;
String charset = "";
try {
content = con.getInputStream();
CloseShieldInputStream csContent = new CloseShieldInputStream(content);
charset = getCharset(csContent);
return IOUtils.toString(content,charset);
} catch (Exception e) {
System.out.println("Error downloading page: " + e);
return null;
}
}
private String getCharset(InputStream content) {
try {
Source parser = new Source(content);
return parser.getEncoding();
} catch (Exception e) {
System.out.println("Error determining charset: " + e);
return "UTF-8";
}
}
发布于 2011-05-08 05:32:09
如果您想要做的就是多次读取相同的信息,并且输入数据足够小,可以放入内存中,那么可以将数据从InputStream
复制到ByteArrayOutputStream。
然后,您可以获得相关的字节数组,并打开任意多个“克隆”的ByteArrayInputStream。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Code simulating the copy
// You could alternatively use NIO
// And please, unlike me, do something about the Exceptions :D
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1 ) {
baos.write(buffer, 0, len);
}
baos.flush();
// Open new InputStreams using recorded bytes
// Can be repeated as many times as you wish
InputStream is1 = new ByteArrayInputStream(baos.toByteArray());
InputStream is2 = new ByteArrayInputStream(baos.toByteArray());
但是,如果您确实需要保持原始流的打开状态以接收新数据,则需要跟踪对close()
的外部调用。您需要以某种方式阻止close()
被调用。
更新(2019):
从Java9开始,中间的部分可以用InputStream.transferTo
代替
ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
InputStream firstClone = new ByteArrayInputStream(baos.toByteArray());
InputStream secondClone = new ByteArrayInputStream(baos.toByteArray());
发布于 2011-05-08 05:09:40
您想要使用Apache的CloseShieldInputStream
:
这是一个包装器,可以防止流被关闭。你会做这样的事。
InputStream is = null;
is = getStream(); //obtain the stream
CloseShieldInputStream csis = new CloseShieldInputStream(is);
// call the bad function that does things it shouldn't
badFunction(csis);
// happiness follows: do something with the original input stream
is.read();
发布于 2011-05-08 04:41:00
你不能克隆它,你将如何解决你的问题取决于数据的来源。
一种解决方案是将所有数据从InputStream读取到一个字节数组中,然后在该字节数组周围创建一个ByteArrayInputStream,并将该输入流传递给您的方法。
编辑1:如果另一个方法也需要读取相同的数据。也就是说,你想要“重置”流。
https://stackoverflow.com/questions/5923817
复制相似问题