ByteArrayOutputStream.toByteArray
ByteArrayInputStream
StringWriter.toString
StringReader
字符流和二進制流是javaIO的兩類流,
輸入流和輸出流是javaIO的兩類流
如果你曾經使用過Java IO 編程,很可能會遇到這樣一個狀況,在一個類中向OutputStream里面寫數據,而另一個類則從InputStream中讀取這些數據。這時問題就出 現了,“如何才能把OutputStream里的數據轉換為InputStream里的數據呢?”。
在Java里,並沒有一個OutpStreamToInputStreamConverter 的類。 但慶幸的是還是有幾個方法可以辦到。
方法1:使用byte數組作為緩存
最簡單的方法就是使用byte 數組作為緩存。代碼示例如下:
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- class1.putDataOnOutputStream(out);
- class2.processDataFromInputStream(
- new ByteArrayInputStream(out.toByteArray())
- );
這樣就行了,OutputStream已經轉換為InputStream。
方法2:使用管道
方法1的問題是你必須有足夠大的緩存來保存所有的數據。很可能就需要使用文件系統而不是內存,但是不論哪種方法都對能處理的數據存規模存在嚴格的限制。解 決的方法是在一個線程中往PipedOutputStream里面寫數據,而當前線程則繼續讀另一個線程輸入的數據。
- PipedInputStream in = new PipedInputStream();
- PipedOUtputStream out = new PipedOutputStream(in);
- new Thread(
- new Runnable(){
- public void run(){
- class1.putDataOnOutputStream(out);
- }
- }
- ).start();
- class2.processDataFromInputStream(in);
方法3:使用循環緩存
方法2里面的兩個管道實際上是維護了一個隱藏的循環緩存。所以明確的使用一個循環緩存可以更加簡便。循環緩存提供了如下幾種好處:
(譯者注:JDK中並沒有提供這種解決方案,感興趣的話可以去http://ostermiller.org/utils/ 下載)
- 一個循環緩存類替代兩個管道類
- 可以很容易的在“緩存所有數據”和“多線程”方法間切換
- 你可以改變緩存的大小,而不是依賴於管道內硬編碼的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());
Writer到Reader 的轉換方法與上述方法類似,下面僅舉例,不做詳細說明了。
方法4:使用緩存數組
- StringWriter out = new StringWriter();
- class1.putDataOnWriter(out);
- class2.processDataFromReader(
- new StringReader(out.toString())
- );
方法5:使用管道
- PipedReader in = new PipedReader();
- PipedWriter out = new PipedWriter(in);
- new Thread(
- new Runnable(){
- public void run(){
- class1.putDataOnWriter(out);
- }
- }
- ).start();
- class2.processDataFromReader(in);
方法6:使用循環緩存
多線程示例
- CircularCharBuffer ccb = new CircularCharBuffer();
- new Thread(
- new Runnable(){
- public void run(){
- class1.putDataOnWriter(ccb.getWriter());
- }
- }
- ).start();
- class2.processDataFromReader(ccb.getReader());
單線程示例
- // buffer all data in a circular buffer of infinite size
- CircularCharBuffer ccb = new CircularCharBuffer(CircularCharBuffer.INFINITE_SIZE);
- class1.putDataOnWriter(ccb.getWriter());
- class2.processDataFromReader(ccb.getReader());
