简体   繁体   English

如何克隆输入流但仍可重复使用原始流

[英]How to clone input stream but still re-use original

I am trying to copy the InputStream from a URLConnection which is returning a stream of type HttpInputStream (inner class of HttpUrlConnection ) 我正在尝试从URLConnection复制InputStream ,该URLConnection返回HttpInputStream类型的流( HttpUrlConnection内部类)

In other cases, I can copy the original stream to a ByteArrayOutputStream and then use mark/reset on the original, but HttpInputStream does not support mark/reset. 在其他情况下,我可以将原始流复制到ByteArrayOutputStream,然后在原始流上使用mark / reset,但是HttpInputStream不支持mark / reset。

Is there a way I can still copy the stream and reset the original or keep it from being consumed? 有什么方法可以让我仍然复制流并重置原始流或防止流被消耗? The original stream inside URLConnection has to be readable because it is passed into another library. URLConnection的原始流必须可读,因为它已传递到另一个库中。 I only need to copy the stream so I can read the first two lines of data. 我只需要复制流,就可以读取数据的前两行。 Here is what I have for streams that support mark/reset: 这是我支持标记/重置的流的内容:

InputStream input = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
      input = connection.getInputStream();
      byte[] buffer = new byte[200];
      input.mark(200);
      int len = input.read(buffer);
      input.reset();
      baos.write(buffer, 0, len);
      baos.flush();

      String content = baos.toString("UTF-8");
      //I set flags based on the value of content, but omitting here for the sake of simplicity.

    } catch (IOException ex) {
      //I do stuff here, but omitting for sake of simplicity in this
    }

ImputStreams are not generally cloneable, and neither do all streams support mark/reset. ImputStream通常不可克隆,并且所有流都不都支持标记/重置。 There are some possible workarounds within the standard JRE. 标准JRE中有一些可能的解决方法。

Wrap the InputStream into a BufferedInputStream. 将InputStream包装到BufferedInputStream中。 That one supports mark/reset within the limits of its buffer size. 支持在缓冲区大小范围内进行标记/重置。 That enables you to read a limited amount of data from the beginning, then reset the stream. 这样一来,您就可以从头开始读取有限数量的数据,然后重置流。

Another alternative is PushBackInputStream, which allows you to "unread" data previously read. 另一个选择是PushBackInputStream,它允许您“未读”以前读取的数据。 You need to buffer the data to be pushed back yourself though, so it may be a bit inconvinient to handle. 但是,您需要缓冲要自己推送的数据,因此处理起来可能有些不便。

If the whole stream isn't terribly big, you could also read the entire stream first, then construct as many ByteArrayInputStreams as needed from the pre-read data. 如果整个流不是很大,您也可以先读取整个流,然后根据需要从预读数据中构造尽可能多的ByteArrayInputStreams。 Only feasible if the data fits in the heap (eg less than approximately 2GB max). 仅当数据适合堆时才可行(例如,最大容量小于约2GB)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM