管道簡介
|
管道的含義,很久之前就已經出現 用於表示數據直接交互 |
它的含義與平時說的管道的含義是類似的,就是直連 JavaIO中的 PipedInputStream 和 PipedOutputStream 就是IO體系中字節流的管道
|
java中,PipedOutputStream和PipedInputStream分別是管道輸出流和管道輸入流 |
使用管道通信時,必須將PipedOutputStream和PipedInputStream配套使用 |
大致流程: 我們在線程A中向PipedOutputStream中寫入數據,這些數據會自動的發送到與PipedOutputStream對應的PipedInputStream中,進而存儲在PipedInputStream的緩沖中; 線程B通過讀取PipedInputStream中的數據 |
對照到我上面畫的圖就是這樣: |
雖然說是管道,跟現實中的含義有些類似,但是也絕對不能認為他們的數據流方向可以任意 在JavaIO中必須是一個線程通過PipedOutputStream 寫入數據,另外的線程通過與他相連接的PipedInputStream讀取數據 |
實現原理
PipedOutputStream 中有一個 pipedInputStream pipedInputStream 內部有一個字節數組 通過initPipe方法進行初始化 |
調用PipedOutputStream的write方法,實際上調用的是內部pipedInputStream 的 receive方法 而 receive方法,操作的正是pipedInputStream內部的字節數組 所以說,只需要使用connect把管道連接起來 就可以通過PipedOutputStream 寫入數據,PipedOutputStream讀取數據 數據的中轉站,正是pipedInputStream 內的數組 |
|
PipedInputStream
剛才已經介紹,PipedInputStream 內部維護了一個字節數組 buffer 默認大小為1024 通過initPipe方法初始化 |
PipedOutputStream 和 PipedInputStream 他們其實操作的都是 PipedInputStream 中的buffer 一個讀一個寫,所以要記住讀和寫的位置
注意 此處的in和 out 是相對於 PipedInputStream 的buffer[] 來說的 所以in就是 PipedOutputStream 調用write最終使用的 out就是 PipedInputStream 本身read使用的 |
想要使用管道流必須要有連接的過程 可以在創建 PipedInputStream 的同時一並連接 或者僅僅創建PipedInputStream 稍后連接 而且,內部字節數組的長度是可以設置的,所以也就是又有了默認的或者設置的兩種形式 所以總共有四種形式的構造方法 |
|
read
public synchronized int read() throws IOException 讀取一個字節 |
public synchronized int read(byte b[], int off, int len) 讀取長度為len的字節到字節數組b 從偏移量off開始寫入 |
available() 獲取可用個數 |
close() 沒有系統資源需要關閉,但是還是有些事情要做 |
connect
connect 調用的是PipedOutputStream中的connect方法 |
|
PipedOutputStream
內部需要PipedInputStream |
構造方法也比較簡單 創建一個PipeOutputStream或者創建的同時進行連接 |
剛才講過,PipedInputStream中的connect也是借助於PipedOutputStream 他完成了真正的連接 看得出來,不能重復連接,否則會拋出異常 連接后,會對連接進來的PipedInputStream進行必要的初始化 主要就是 in和 out 另外標記已經連接,也正是用這個connected字段來校驗是否已經連接的 |
write
兩個版本的write方法 write(int b) 寫入一個字節, 前面24位會被丟棄 write(byte b[], int off, int len) 從指定字節數組的指定位置,讀取指定個數的字節, 寫入到流 根本還是調用的receive |
|
flush
flush 將數據輸出,此處不同於文件需要調用操作系統進行寫入磁盤 需要通知讀線程進行讀取 |
|
close
|
對於管道流的學習,只需要了解其根本即可,那就是PipedOutputStream 內部指向了一個 PipedInputStream
借助於PipedInputStream 內部的循環數組進行數據緩存,進而達到多線程通信的目的
read 和 write方法的含義用法跟InputStream要求的是一樣的,沒什么特別的
實現細節有興趣的可以深入研究