小编典典

如何克隆 InputStream?

all

我有一个 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";
    }
}

阅读 137

收藏
2022-07-28

共1个答案

小编典典

如果您只想多次读取相同的信息,并且输入数据足够小以适合内存,则可以将数据从您的数据复制InputStreamByteArrayOutputStream

然后,您可以获得相关的字节数组并打开任意数量的“克隆”
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):

从 Java 9
开始,中间位可以替换为InputStream.transferTo

ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
InputStream firstClone = new ByteArrayInputStream(baos.toByteArray()); 
InputStream secondClone = new ByteArrayInputStream(baos.toByteArray());
2022-07-28