当我从InputStream到OutputStream读取数据时,如何动态地压缩数据?

时间:2013-01-31 22:41:53

标签: java gzip inputstream

我有一个包含gzip压缩数据的大InputStream

我无法直接修改InputStream中的数据。稍后使用此InputStream的代码需要未经修改的压缩数据。如果需要,我可以使用新的InputStream替换InputStream,但数据必须保持压缩状态。

出于调试目的,我需要打印InputStream的未压缩内容。

InputStream中未压缩数据打印到PrintStream的最简单方法是什么,而不会不可挽回地解压缩InputStream本身而不将整个内容读入内存?

1 个答案:

答案 0 :(得分:1)

我是这样做的。

// http://stackoverflow.com/a/12107486/82156
public static InputStream wrapInputStreamAndCopyToOutputStream(InputStream in, final boolean gzipped, final OutputStream out) throws IOException {
    // Create a tee-splitter for the other reader.
    final PipedInputStream inCopy = new PipedInputStream();
    final TeeInputStream inWrapper = new TeeInputStream(in, new PipedOutputStream(inCopy));

    new Thread(Thread.currentThread().getName() + "-log-writer") {
        @Override
        public void run() {
            try {
                IOUtils.copy(gzipped ? new GZIPInputStream(inCopy) : inCopy, new BufferedOutputStream(out));
            } catch (IOException e) {
                Log.e(TAG, e);
            }
        }
    }.start();
    return inWrapper;
}

此方法包装原始InputStream并返回包装器,从现在开始您需要使用它(不要使用原始的InputStream)。然后,它使用Apache Commons TeeInputStream使用线程将数据复制到PipedOutputStream,可选择将其解压缩。

要使用,只需执行以下操作:

InputStream inputStream = ...; // your original inputstream
inputStream = wrapInputStreamAndCopyToOutputStream(inputStream,true,System.out); // wrap your inputStream and copy the data to System.out

doSomethingWithInputStream(inputStream); // Consume the wrapped InputStream like you were already going to do

后台线程将一直存在,直到前台线程消耗整个输入流,以块为单位缓冲输出并定期将其写入System.out,直到完成所有操作。