首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何克隆InputStream?

如何克隆InputStream?
EN

Stack Overflow用户
提问于 2011-05-08 04:34:07
回答 6查看 161K关注 0票数 182

我有一个InputStream,我将它传递给一个方法进行一些处理。我将在其他方法中使用相同的InputStream,但是在第一次处理之后,InputStream似乎在该方法中是封闭的。

我如何克隆要发送给关闭他的方法的InputStream?还有其他的解决方案吗?

编辑:关闭InputStream的方法是库中的外部方法。我不能控制关闭与否。

代码语言:javascript
复制
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";
    }
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-05-08 05:32:09

如果您想要做的就是多次读取相同的信息,并且输入数据足够小,可以放入内存中,那么可以将数据从InputStream复制到ByteArrayOutputStream

然后,您可以获得相关的字节数组,并打开任意多个“克隆”的ByteArrayInputStream

代码语言:javascript
复制
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代替

代码语言:javascript
复制
ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
InputStream firstClone = new ByteArrayInputStream(baos.toByteArray()); 
InputStream secondClone = new ByteArrayInputStream(baos.toByteArray()); 
票数 217
EN

Stack Overflow用户

发布于 2011-05-08 05:09:40

您想要使用Apache的CloseShieldInputStream

这是一个包装器,可以防止流被关闭。你会做这样的事。

代码语言:javascript
复制
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();
票数 34
EN

Stack Overflow用户

发布于 2011-05-08 04:41:00

你不能克隆它,你将如何解决你的问题取决于数据的来源。

一种解决方案是将所有数据从InputStream读取到一个字节数组中,然后在该字节数组周围创建一个ByteArrayInputStream,并将该输入流传递给您的方法。

编辑1:如果另一个方法也需要读取相同的数据。也就是说,你想要“重置”流。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5923817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档