目录
简介
package java.io;
import java.io.*;
/**
* 可以将管道输出流连接到管道输入流以创建通信管道。
* 管道输出流是管道的发送端。
* 通常,数据由一个线程写入到PipedOutputStream对象,数据由其他线程从连接的PipedInputStream读取。
* 不建议在一个线程中同时使用两个对象,因为这可能导致线程死锁。
* 如果正在从连接的PipedInputStream读取数据字节的线程不再是活的,那么管道就被认为被破坏了。
*
* @author James Gosling
* @see java.io.PipedInputStream
* @since JDK1.0
*/
public
class PipedOutputStream extends OutputStream
字段sink,2个构造函数
/* 提醒:读写侧的识别需要更加复杂。
要么使用线程组(但是线程中的管道呢?),要么使用终结(但是到下一次GC可能需要很长时间)。
*/
// sink是一个PipedInputStream
private PipedInputStream sink;
/**
* 创建连接到指定PipedInputStream的管道输出流。
* 写入该流的数据字节将作为snk的可用输入。
*
* @param snk The piped input stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public PipedOutputStream(PipedInputStream snk) throws IOException {
connect(snk);
}
/**
* 创建尚未连接到PipedInputStream的管道输出流。
* 在使用之前,它必须由接收方或发送方连接到管道输入流。
*
* @see java.io.PipedInputStream#connect(java.io.PipedOutputStream)
* @see java.io.PipedOutputStream#connect(java.io.PipedInputStream)
*/
public PipedOutputStream() {
}
connect方法,2个write方法
/**
* 将这个管道输出流连接到一个接收器。
* 如果该对象已经连接到其他管道输入流,则抛出IOException。
* <p>
* 如果snk是一个未连接的管道输入流,
* 而src是一个未连接的管道输出流,它们可能通过以下任一调用连接:
*
* <blockquote><pre>
* src.connect(snk)</pre></blockquote>
* or the call:
* <blockquote><pre>
* snk.connect(src)</pre></blockquote>
* 这两个调用具有相同的效果。
*
* @param snk the piped input stream to connect to.
* @exception IOException if an I/O error occurs.
*/
public synchronized void connect(PipedInputStream snk) throws IOException {
if (snk == null) {
throw new NullPointerException();
} else if (sink != null || snk.connected) {
throw new IOException("Already connected");
}
// 赋值sink为snk
sink = snk;
// 设置snk的in,out,connected属性
snk.in = -1;
snk.out = 0;
snk.connected = true;
}
/**
* 将指定的字节写入管道输出流。
* <p>
* 实现OutputStream的写方法。
*
* @param b the <code>byte</code> to be written.
* @exception IOException if the pipe is <a href=#BROKEN> broken</a>,
* {@link #connect(java.io.PipedInputStream) unconnected},
* closed, or if an I/O error occurs.
*/
public void write(int b) throws IOException {
if (sink == null) {
throw new IOException("Pipe not connected");
}
// 调用sink的receive方法
sink.receive(b);
}
/**
* 将指定字节数组从off位置开始的len字节写入此管道输出流。
* 此方法将阻塞,直到所有字节都写入到outputstream。
*
* @param b the data.
* @param off the start offset in the data.
* @param len the number of bytes to write.
* @exception IOException if the pipe is <a href=#BROKEN> broken</a>,
* {@link #connect(java.io.PipedInputStream) unconnected},
* closed, or if an I/O error occurs.
*/
public void write(byte b[], int off, int len) throws IOException {
if (sink == null) {
throw new IOException("Pipe not connected");
} else if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
sink.receive(b, off, len);
}
flush方法,close方法
/**
* 刷新此输出流,并强制将所有缓冲的输出字节写入。
* 这将通知任何读取器字节正在管道中等待。
*
* @exception IOException if an I/O error occurs.
*/
public synchronized void flush() throws IOException {
if (sink != null) {
synchronized (sink) {
sink.notifyAll();
}
}
}
/**
* 关闭此管道输出流,并释放与此流关联的任何系统资源。
* 此流可能不再用于写入字节。
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
if (sink != null) {
sink.receivedLast();
}
}