管道流
在Java语言中提供了各种各样的输入/输出流Stream,使我们能够很方便的对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于不同线程间直接传送数据。一个线程发送数据到输出管道,另一个线程从输入管道中读数据。通过使用管道,实现不同线程间的通信,而无须借助于类似临时文件之类的东西。
在Java的JDK中提供了4个类来使线程间可以进行通信:
1) PipedInputStream和PipedOutputStream(字节流)
2) PipedReader和PipedWriter(字符流)
管道字节流
//类WriteData.java:
package test;
import java.io.IOException;
import java.io.PipedOutputStream;
public class WriteData {
public void writeMethod(PipedOutputStream out) {
try {
System.out.println("write :");
for(int i = 0; i < 300; i++) {
String outData = "" + (i + 1);
out.write(outData.getBytes());//将一个字符转化为字节,然后写入管道
System.out.print(outData);
Thread.sleep(1000);//加上这句,可以看到管道是边写边读的
}
System.out.println();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//类ReadData.java:
package test;
import java.io.IOException;
import java.io.PipedInputStream;
public class ReadData {
public void readMethod(PipedInputStream input) {
System.out.println("read :");
byte[] byteArray = new byte[20];
try {
int readLength = input.read(byteArray);//从管道中读取最多20字节的数据存入byteArray数组,并返回数组长度
while(readLength != -1) {//只要管道还有数据,就一直读
String newData = new String(byteArray, 0, readLength);
System.out.print(newData);
readLength = input.read(byteArray);//再次从管道中读取最多20字节数据
}
System.out.println();
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//类ThreadWrite.java:
package test;
import java.io.PipedOutputStream;
public class ThreadWrite extends Thread{
private WriteData write;
private PipedOutputStream out;
public ThreadWrite(WriteData write, PipedOutputStream out) {
this.write = write;
this.out = out;
}
public void run() {
write.writeMethod(out);
}
}
//ThreadRead.java:
package test;
import java.io.PipedInputStream;
public class ThreadRead extends Thread{
private ReadData read;
private PipedInputStream input;
public ThreadRead(ReadData read, PipedInputStream input) {
this.read = read;
this.input = input;
}
public void run() {
read.readMethod(input);
}
}
使用代码inputStream.connect(outputStream)或outputStream.connect(inputStream)的作用是使两个Stream之间产生通信链接,这样才可以将数据进行输出与输入。
从程序打印结果来看,两个线程通过管道流成功进行数据的传输。
但在此实验中,首先是读取线程new ThreadRead(inputStream)启动,由于当时没有数据被写入,所以线程阻塞在int readLength=in.read(byteArray);代码中,直到有数据被写入,才继续向下运行。
管道字符流
//WriteData.java:
package test;
import java.io.IOException;
import java.io.PipedWriter;
public class WriteData {
public void writeMethod(PipedWriter out) {
try {
System.out.println("write :");
for(int i = 0; i < 300; i++) {
String outData = "" + (i + 1);
out.write(outData);//将字符直接写入管道
System.out.print(outData);
Thread.sleep(1000);//加上这句,可以看到管道是边写边读的
}
System.out.println();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ReadData.java类:
package test;
import java.io.IOException;
import java.io.PipedReader;
public class ReadData {
public void readMethod(PipedReader input) {
System.out.println("read :");
char[] byteArray = new char[20];
try {
int readLength = input.read(byteArray);//从管道中读取最多20个字符的数据存入byteArray数组,并返回数组长度
while(readLength != -1) {//只要管道还有数据,就一直读
String newData = new String(byteArray, 0, readLength);
System.out.print(newData);
readLength = input.read(byteArray);//再次从管道中读取最多20字符数据
}
System.out.println();
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//ThreadWrite.java
package test;
import java.io.PipedWriter;
public class ThreadWrite extends Thread{
private WriteData write;
private PipedWriter out;
public ThreadWrite(WriteData write, PipedWriter out) {
this.write = write;
this.out = out;
}
public void run() {
write.writeMethod(out);
}
}
//ThreadRead.java
package test;
import java.io.PipedReader;
public class ThreadRead extends Thread{
private ReadData read;
private PipedReader input;
public ThreadRead(ReadData read, PipedReader input) {
this.read = read;
this.input = input;
}
public void run() {
read.readMethod(input);
}
}
//Run.java
package test;
import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;
public class Run {
public static void main(String[] args) {
WriteData writeData = new WriteData();
ReadData readData = new ReadData();
PipedWriter pipedWriter = new PipedWriter();
PipedReader pipedReader = new PipedReader();
try {
// pipedReader.connect(pipedWriter);
pipedWriter.connect(pipedReader);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ThreadRead threadRead = new ThreadRead(readData, pipedReader);
threadRead.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ThreadWrite threadWrite =new ThreadWrite(writeData, pipedWriter);
threadWrite.start();
}
}
运行结果和字节流传输是一样的。