java IO 管道流学习记录

理解:

java中管道流的功能是可以将一个输出流作为另一个线程的输入流,我的理解就是将一个输出流链接到输入流,那么输出流输出的数据将可以用对应的输入流来读取。一般管道流用于多线程之间的通信,所以一般只有多线程的情况下才会用到。

基本类说明:

管道流按方向分为输入流和输出流,按类型分为字符流和字节流。和其他的字节流和字符流一样。

PipedInputStream  管道输入流

PipedOutputStream 管道输出流

链接管道输入和输出流时,使用管道输出流的connect(PipedInputStream) 方法,将管道输入流类型的对象作为方法参数传入即可。

声明其他基本的输入输出流时,可以使用管道输入输出流作为参数传入, 这样输入或者输出时就会从管道流中运输。

注意

PipedInputStream中实际是用了一个1024字节固定大小的循环缓冲区。写入PipedOutputStream的数据实际上保存到对应的 PipedInputStream的内部缓冲区。从PipedInputStream执行读操作时,读取的数据实际上来自这个内部缓冲区。如果对应的 PipedInputStream输入缓冲区已满,任何企图写入PipedOutputStream的线程都将被阻塞。而且这个写操作线程将一直阻塞,直至出现读取PipedInputStream的操作从缓冲区删除数据。所以如果管道输入流和管道输出流是同一个线程时,很可能出现阻塞的问题,所以一般在多线程中使用。


下面看一个代码的小示例

//发送方,输出流
public class Send implements Runnable {

	//data类型的输出流
	private DataOutputStream outputStream;
	private Random random = new Random();
	
	public Send(PipedOutputStream outputStream){
		this.outputStream = new DataOutputStream(outputStream);
	}
	
	public void run() {
		//循环输出随机数,2秒间隔
		while(true){
			try {
				outputStream.writeInt(random.nextInt());
				outputStream.flush();
				Thread.sleep(2000);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

//接收方,输入流
public class Recive implements Runnable{

	private DataInputStream inputStream;
	
	public Recive(PipedInputStream inputStream){
		this.inputStream = new DataInputStream(inputStream);
	}
	
	public void run() {
		//循环读取
		while(true){
			try {
				int num = inputStream.readInt();
				System.out.println(num);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

public class Test {
	public static void main(String[] args) {
		PipedInputStream pipedIS = new PipedInputStream();
		PipedOutputStream pipedOS = new PipedOutputStream();
		try {
			//链接输入,输出流
			pipedOS.connect(pipedIS);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Send send = new Send(pipedOS);
		Recive recive = new Recive(pipedIS);
		new Thread(send).start();
		new Thread(recive).start();
	}
}


你可能感兴趣的:(IO流)