Java IO學習筆記五
管道流
- 管道流的主要作用是可以進行兩個執行緒間的通訊,分為管道輸出流(
PipedOutputStream
)、管道輸入流(PipedInputStream
),如果想要進行管道輸出,則必須要把輸出流連在輸入流之上,在PipedOutputStream類上有如下的一個方法用於連線管道:public void connect(PipedInputStream snk)throws IOException
- 通常是建立兩個單獨的執行緒來實現通訊,如果是單個執行緒的話容易出現執行緒堵塞,因為輸出流最多隻能向緩衝區寫入1024個位元組的資料,如果超出就會出現執行緒堵塞,因此必須建立多個執行緒實現緩衝區的釋放和儲存
PipedOutputStream
- 管道輸出流是管道的傳送端,可以將管道輸出流連線到管道輸入流來建立一個通訊管道,通常,資料由某個執行緒寫入
PipedOutputStream
物件,並由其他執行緒從連線的PipedInputStream
讀取。不建議對這兩個物件嘗試使用單個執行緒,因為這樣可能會造成該執行緒死鎖。如果某個執行緒正從連線的管道輸入流中讀取資料位元組,但該執行緒不再處於活動狀態,則該管道被視為處於 毀壞 狀態。
建構函式
PipedOutputStream()
建立尚未連線到管道輸入流的管道輸出流。PipedOutputStream(PipedInputStream snk)
建立連線到指定管道輸入流的管道輸出流。
常用函式
close()
關閉void connect(PipedInputStream snk)
將此管道輸出流連線到接收者。void flush()
重新整理此輸出流並強制寫出所有緩衝的輸出位元組。void write(byte[] b, int off, int len)
將len
位元組從初始偏移量為off
的指定byte
陣列寫入該管道輸出流。void write(int b)
將指定byte
寫入傳送的輸出流。
PipedInputStream
- 管道輸入流應該連線到管道輸出流;管道輸入流提供要寫入管道輸出流的所有資料位元組。通常,資料由某個執行緒從
PipedInputStream
物件讀取,並由其他執行緒將其寫入到相應的PipedOutputStream
。不建議對這兩個物件嘗試使用單個執行緒,因為這樣可能死鎖執行緒。管道輸入流包含一個緩衝區,可在緩衝區限定的範圍內將讀操作和寫操作分離開。 如果向連線管道輸出流提供資料位元組的執行緒不再存在,則認為該管道已損壞。
建構函式
PipedInputStream()
建立尚未連線的PipedInputStream
。PipedInputStream(PipedOutputStream src)
建立PipedInputStream
,使其連線到管道輸出流src
。
常用函式
int available()
返回可以不受阻塞地從此輸入流中讀取的位元組數。void close()
關閉此管道輸入流並釋放與該流相關的所有系統資源。void connect(PipedOutputStream src)
使此管道輸入流連線到管道輸出流src
。int read()
讀取此管道輸入流中的下一個資料位元組。int read(byte[] b, int off, int len)
將最多len
個資料位元組從此管道輸入流讀入byte
陣列。protected void receive(int b)
接收資料位元組。
例項
package IO;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
* Created by chenjiabing on 17-5-25.
*/
/**
* 注意的問題:
* 1.寫執行緒正在往緩衝區寫資料的時候,但是此時的讀執行緒的管道結束,那麼此時的寫執行緒的管道就會發生IOException異常
* 2.讀執行緒正在從緩衝區讀資料的時候,但是此時的寫執行緒的管道已經結束了,此時就會引起讀執行緒的管道發生IOException異常
* 3.必須是啟用多執行緒才能實現管道之間的讀寫,否則會出現堵塞現象,因為這裡的PipeOutputStream每次向緩衝區寫入的位元組數最大是1024,如果不及時的減少緩衝區的資料量就會出現堵塞
*/
public class demo7 {
public static PipedOutputStream outputStream = new PipedOutputStream();
public static PipedInputStream inputStream = new PipedInputStream();
/**
* 建立一個寫入資料程式,使用的是PipeOutStream,將資料寫入管道中
*/
public static void send() {
new Thread(new Runnable() {
@Override
public void run() {
byte[] bytes = new byte[2000]; //建立一個2000位元組的陣列
while (true) {
try {
outputStream.write(bytes, 0, 2000); //寫入管道,但是這裡的緩衝區最多寫入1024個位元組的資料,因此這個是一次沒有寫完
System.out.println("寫入成功");
} catch (IOException e) {
System.out.println("寫入失敗");
System.exit(1);
}
}
}
}).start();
}
/**
* 使用PipeInputStream建立一個讀取的執行緒
*/
public static void receive() {
new Thread(new Runnable() {
@Override
public void run() {
byte[] bytes = new byte[100]; //一次性只讀取100個位元組
int len = 0;
try {
len = inputStream.read(bytes, 0, 100); //讀取
while (len != -1) {
System.out.println("已經讀取了" + len + "個位元組");
len = inputStream.read(bytes, 0, 100);
}
} catch (IOException e) {
System.out.println("讀取失敗");
System.exit(1);
}
}
}).start();
}
public static void main(String args[]) {
try {
inputStream.connect(outputStream); //連線
} catch (IOException e) {
System.out.println("連線失敗");
System.exit(1);
}
send();
receive();
}
}
注意:從上面的執行結果可以看出,緩衝區最多可以寫入
1024
個位元組的資料,所以在緩衝區滿了之後上面的send
程式就會堵塞等待緩衝區空閒,如果recieve
程式不繼續讀取資料了,那麼就會一直出現堵塞
問題
- 寫執行緒正在往緩衝區寫資料的時候,但是此時的讀執行緒的結束讀取,那麼此時的寫執行緒的管道就會發生
IOException
異常,可以將上面receive
程式中的while(true)
去掉就可以清楚的看出- 讀執行緒正在從緩衝區讀資料的時候,但是此時的寫執行緒的管道已經結束了,此時就會引起讀執行緒的管道發生
IOException
異常,將上面的send
程式中的while(true)
去掉就可以實現這個問題- 必須是啟用多執行緒才能實現管道之間的讀寫,否則會出現堵塞現象,因為這裡的
PipeOutputStream
每次向緩衝區寫入的位元組數最大是1024
,如果不及時的減少緩衝區的資料量就會出現堵塞
解決方法
- 後續更新中..........
參考文章
相關文章
- Java IO學習筆記五:BIO到NIOJava筆記
- Java學習筆記09(IO流)Java筆記
- Java IO學習筆記八:Netty入門Java筆記Netty
- Java IO學習筆記四:Socket基礎Java筆記
- Java IO學習筆記二:DirectByteBuffer與HeapByteBufferJava筆記
- Java IO學習筆記六:NIO到多路複用Java筆記
- 基礎 IO (Linux學習筆記)Linux筆記
- JVM 學習筆記(五)JVM筆記
- cmake學習筆記(五)筆記
- 第五天學習Java的筆記Java筆記
- Linux程式設計學習筆記 | Linux IO學習[2] – 標準IOLinux程式設計筆記
- Java筆記-IO流Java筆記
- IO——簡略的學習筆記(1)筆記
- nodejs的socket.io學習筆記NodeJS筆記
- Java設計模式學習筆記(五) 單例模式Java設計模式筆記單例
- JAVA學習筆記Java筆記
- DP學習筆記(五)(2024.11.16)筆記
- c++學習筆記(五)C++筆記
- Kubernetes學習筆記(五):卷筆記
- 字典--Python學習筆記(五)Python筆記
- 《JAVA學習指南》學習筆記Java筆記
- Jenkinsant介紹(學習筆記五)Jenkins筆記
- Qt學習筆記(五)QString 字串QT筆記字串
- Java學習筆記4Java筆記
- Java JNI 學習筆記Java筆記
- java學習筆記6Java筆記
- Java 集合學習筆記Java筆記
- Java學習筆記記錄(二)Java筆記
- 《Java核心技術》第五章 繼承 學習筆記Java繼承筆記
- hive學習筆記之五:分桶Hive筆記
- Netty學習筆記(五)NioEventLoop啟動Netty筆記OOP
- TypeScript學習筆記之五類(Class)TypeScript筆記
- springcloud學習筆記(五)Spring Cloud ActuatorSpringGCCloud筆記
- Java基礎學習筆記Java筆記
- 【部分】Java速成學習筆記Java筆記
- Java學習筆記--運算子Java筆記
- Kotlin for Java Developers 學習筆記KotlinJavaDeveloper筆記
- java學習筆記(異常)Java筆記
- 【Java學習筆記】Collections集合Java筆記