原文地址:
http://ostermiller.org/convert_java_outputstream_inputstream.html
如果你曾經(jīng)使用java IO編程,你會很快碰到這種情況,某個類在OutputStream上創(chuàng)建數(shù)據(jù)而你需要將它發(fā)送給某個需要從輸入流讀取數(shù)據(jù)的類。
你很快會被問道,“java中如何將OutputStream轉換為InputStream?”
方法一:使用字節(jié)數(shù)組緩存數(shù)據(jù)
最簡單的方法是用字節(jié)數(shù)組緩存數(shù)據(jù)。代碼如下:
ByteArrayOutputStream out = new ByteArrayOutputStream();
class1.putDataOnOutputStream(out);
class2.processDataFromInputStream(
new ByteArrayInputStream(out.toByteArray())
);
于是,OutputStream就被轉換為InputStream了。
方法二:使用管道
第一種方法的問題是你必須有足夠的內(nèi)存緩存所有數(shù)據(jù)。你可以使用文件系統(tǒng)緩存更多數(shù)據(jù),但無論如何可處理數(shù)據(jù)的大小還是受到限制。
解決方法是創(chuàng)建一個線程產(chǎn)生數(shù)據(jù)到PipedOutputStream。當前線程可從中讀取數(shù)據(jù)。
PipedInputStream in = new PipedInputStream();
PipedOUtputStream out = new PipedOutputStream(in);
new Thread(
new Runnable(){
public void run(){
class1.putDataOnOutputStream(out);
}
}
).start();
class2.processDataFromInputStream(in);
方法三:使用循環(huán)緩存區(qū)
方法二中的兩個管道流,實際上管理著一個隱藏的循環(huán)緩存區(qū)。使用一個顯式的循環(huán)緩存區(qū)更易于理解。CircularBuffers 有如下優(yōu)點:
一個CircularBuffers類而不是兩個管道類。
較于緩存所有數(shù)據(jù)和額外線程的方法更容易使用。
你可以更改緩存大小而不必受限于管道緩存區(qū)1K的固定緩存大小。
多線程情形:
CircularByteBuffer cbb = new CircularByteBuffer();
new Thread(
new Runnable(){
public void run(){
class1.putDataOnOutputStream(cbb.getOutputStream());
}
}
).start();
class2.processDataFromInputStream(cbb.getInputStream());
單線程情形:
// buffer all data in a circular buffer of infinite size
CircularByteBuffer cbb = new CircularByteBuffer(CircularByteBuffer.INFINITE_SIZE);
class1.putDataOnOutputStream(cbb.getOutputStream());
class2.processDataFromInputStream(cbb.getInputStream());