簡(jiǎn)介:
PipedInputStream/PipedReader :管道輸入流嗤无,主要在線程中使用 . 管道輸入流是指一個(gè)通訊管道的接收端(Receiver)酱虎。
PipedOutputStream/PipedWriter :管道輸出流舅柜,指在一個(gè)通訊管道的發(fā)送端(Sender)
主要應(yīng)用:一個(gè)線程通過(guò)管道輸出流發(fā)送數(shù)據(jù)肛循,而另一個(gè)線程通過(guò)管道輸入流讀取數(shù)據(jù)口蝠,這樣可實(shí)現(xiàn)兩個(gè)線程間的通訊祷杈。
使用方法:
(1)在使用管道輸出流和管道輸入流時(shí)需要定義兩個(gè)線程類(實(shí)現(xiàn)Runnable或繼承Thread)
(2)在線程的發(fā)送端(Sender)內(nèi)部,定義管道輸出流:
public class Sender implements Runnable{
private PipedOutputStream pos;
//建立一個(gè)輸出流對(duì)象通過(guò)發(fā)送端的構(gòu)造函數(shù)傳遞
Sender(PipedOutputStream pos){
this.pos = pos;
}
@Override
public void run() {
//寫(xiě)入到輸出流中
for(int i = 75;i < 90 ;i++){
try {
pos.write(i);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
//寫(xiě)完記得關(guān)閉流對(duì)象
pos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)在線程的接收端內(nèi)部谴餐,定義管道輸入流:
public class Receiver implements Runnable{
private PipedInputStream pis = null;
//建立構(gòu)造函數(shù)傳遞一個(gè)管道輸入流對(duì)象捌显。
Receiver(PipedInputStream pis){
this.pis = pis;
}
//實(shí)現(xiàn)線程部分代碼:
@Override
public void run() {
int len = 0;
//讀取管道內(nèi)的數(shù)據(jù)
try {
while((len = pis.read()) != -1){
System.out.println("Random: " + (char)len);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
pis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(4)在主線程中需要完成:1)管道流的實(shí)例對(duì)象的生成;2)管道流的連接总寒;3)實(shí)例化線程的接收端和發(fā)送端并把管道流傳遞進(jìn)去;4)開(kāi)啟線程理肺。
public class Test {
public static void main(String[] args) throws IOException {
//分別創(chuàng)建輸入流/輸出流
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
//鏈接輸入輸出流
pos.connect(pis);
//實(shí)例化發(fā)送端接收端
Sender sender = new Sender(pos);
Receiver receiver = new Receiver(pis);
//創(chuàng)建并啟動(dòng)線程
new Thread(sender).start();;
new Thread(receiver).start();;
}
}
同樣字符流應(yīng)用在管道流中摄闸,下面就舉一個(gè)列子利用管道流進(jìn)行文件的復(fù)制:
接收端代碼:線程的接收端-->管道輸出端-->文件的輸入端;
/**
* 從管道輸入流中讀取數(shù)據(jù)妹萨,利用文件輸出流寫(xiě)到文件中
*/
public class Receiver implements Runnable {
// 建立字符管道輸入流年枕,文件輸出流,
private PipedReader pr = null;
private FileWriter fw;
private File file;
// 構(gòu)造參數(shù)接受一個(gè)管道輸入流乎完,和一個(gè)File對(duì)象作為輸出文件的地址
Receiver(PipedReader pr, File file) {
this.pr = pr;
this.file = file;
}
// 實(shí)現(xiàn)線程部分代碼:
@Override
public void run() {
try {
fw = new FileWriter(file);
} catch (IOException e) {
System.out.println("文件不存在");
}
// 讀取管道內(nèi)的數(shù)據(jù)熏兄,并寫(xiě)入文件輸出流中
int data = 0;
try {
while ((data = pr.read()) != -1) {
fw.write((char) data);
fw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
//關(guān)閉流
try {
fw.close();
pr.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
發(fā)送端代碼:線程的發(fā)送端-->管道輸入端-->文件的輸出端;
/**
* 從文件中讀出數(shù)據(jù)進(jìn)入文件輸入流,并把文件輸出流中的數(shù)據(jù)寫(xiě)入管道輸出流中
*/
public class Sender implements Runnable {
private File file;
private FileReader fr;
private PipedWriter pw;
Sender(PipedWriter pw, File file) {
this.pw = pw;
this.file = file;
}
@Override
public void run() {
try {
fr = new FileReader(file);
int data = 0;
while ((data = fr.read()) != -1) {
pw.write((char) data);
pw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
fr.close();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
主線程代碼:
public class Test {
public static void main(String[] args) throws IOException {
File R_file = new File("d://text.txt");
File S_file = new File("d://sc.txt");
//分別創(chuàng)建輸入流/輸出流
PipedReader pr = new PipedReader();
PipedWriter pw = new PipedWriter();
//鏈接輸入輸出流
pr.connect(pw);
//實(shí)例化發(fā)送端接收端
Sender sender = new Sender(pw,R_file);
Receiver receiver = new Receiver(pr,S_file);
//創(chuàng)建并啟動(dòng)線程
new Thread(sender).start();;
new Thread(receiver).start();;
}
}
可以看到:IO操作在實(shí)際應(yīng)用的過(guò)程中可能會(huì)因?yàn)樾枨笄短资褂媚ν啊>唧w什么時(shí)候該選擇什么流對(duì)象桥状,在IO最后會(huì)有總結(jié);