java如何克隆输入流?
我有一个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";
}
}
# 1 楼答案
如果从流中读取的数据很大,我建议使用ApacheCommons IO中的TeInputStream。这样,您就可以复制输入,并将t’d管道作为克隆传递
# 2 楼答案
如果您只想多次读取相同的信息,并且输入数据足够小,可以将数据从
InputStream
复制到ByteArrayOutputStream中然后,您可以获得相关的字节数组,并打开任意多个“克隆的”ByteArrayInputStream
但是,如果您确实需要保持原始流打开以接收新数据,那么您将需要跟踪对
close()
的外部调用。您需要防止以某种方式调用close()
更新(2019年):
由于Java 9,中间位可以替换为^{} :
# 3 楼答案
你不能克隆它,你将如何解决你的问题取决于数据的来源
一种解决方案是将InputStream中的所有数据读取到字节数组中,然后围绕该字节数组创建ByteArrayInputStream,并将该输入流传递到方法中
编辑1: 也就是说,如果另一个方法也需要读取相同的数据。即,您希望“重置”流
# 4 楼答案
这可能在所有情况下都不起作用,但我做到了:我扩展了FilterInputStream类,并在外部lib读取数据时对字节进行必要的处理
然后,您只需传递一个
StreamBytesWithExtraProcessingInputStream
实例,您将在其中传递输入流。使用原始输入流作为构造函数参数需要注意的是,这是一个字节对一个字节的操作,所以如果需要高性能,就不要使用它强>
# 5 楼答案
您想使用Apache的^{} :
这是一个包装器,可以防止流被关闭。你会这样做的
# 6 楼答案
UPD。 检查之前的评论。这不完全是被问到的
如果您使用的是
apache.commons
,则可以使用IOUtils
复制流您可以使用以下代码:
以下是适合您的情况的完整示例:
此代码需要一些依赖项:
MAVEN
GRADLE
以下是此方法的文档参考:
您可以在此处找到有关
IOUtils
的更多信息: http://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html#toBufferedInputStream(java.io.InputStream)