以下是我做到的。
// 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後臺線程將堅持圍繞直到全部完成。
底層數據來自哪裏?如果['markSupported'](http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#markSupported())爲true,那麼'reset'可以提供幫助。如果沒有,你將不得不復制壓縮流的內容並解壓。您將*必須*轉到流尾以打印未壓縮的文件。 –
我不明白爲什麼我不得不這樣做。似乎我可以開球流,讓一個未修改,然後解壓縮另一個... – emmby
這與我所說的沒有太大的不同。問題是,在某些情況下,您將無法倒回到流上的標記;所以你需要讀一次並將它寫入兩個緩衝區 - 一個是未壓縮的,另一個是未修改的。 –