Java 日看一類(43)之IO包中的PipedOutputStream類

該類繼承自OutputStream

引入了IO包(本來就是這個包裏的,引得沒看懂)



該類的類頭註釋如下:

/**
 * A piped output stream can be connected to a piped input stream
 * to create a communications pipe. The piped output stream is the
 * sending end of the pipe. Typically, data is written to a
 * <code>PipedOutputStream</code> object by one thread and data is
 * read from the connected <code>PipedInputStream</code> by some
 * other thread. Attempting to use both objects from a single thread
 * is not recommended as it may deadlock the thread.
 * The pipe is said to be <a name=BROKEN> <i>broken</i> </a> if a
 * thread that was reading data bytes from the connected piped input
 * stream is no longer alive.
 *
 * @author  James Gosling
 * @see     java.io.PipedInputStream
 * @since   JDK1.0
 */

大意如下:

管道輸出流可以與管道輸入流連接成可用的通信管道

管道輸出流是管道的發送段

典型情況下,數據會被某線程寫入管道輸出流,然後會被與其鏈接的管道輸入流通過其他線程讀出

建議使用這兩個類時不要使用單線程(可能會造成死鎖)

如果某個線程正從連接的管道輸入流中讀取數據字節,但該線程不再處於活動狀態,則該管道被視爲斷裂



該類含有如下的成員變量:

與其相連接的管道輸入流

private PipedInputStream sink;



該類含有如下的成員方法:

構造函數(與給定的輸入流相鏈接

public PipedOutputStream(PipedInputStream snk)  throws IOException {
    connect(snk);
}

構造函數(空,不鏈接

public PipedOutputStream() {
}

與輸入流相鏈接

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;//綁定對象
    snk.in = -1;//緩存空間偏移量修改
    snk.out = 0;
    snk.connected = true;
}

寫入一個字節

public void write(int b)  throws IOException {
    if (sink == null) {
        throw new IOException("Pipe not connected");
    }
    sink.receive(b);//輸入流接收
}

寫入一個字節數組

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);
}

刷新輸出流(寫出底層流緩衝的數據,並且喚醒沉睡的reader線程

public synchronized void flush() throws IOException {
    if (sink != null) {
        synchronized (sink) {//保證控制權
            sink.notifyAll();//喚起reader線程讀取緩衝數據
        }
    }
}

關閉管道(釋放資源

public void close()  throws IOException {
    if (sink != null) {
        sink.receivedLast();//關閉了寫入端,並且喚醒讀取線程讀取剩餘緩存
    }
}



該類的操作主要都是通過調用PipedInputStream類,相當於把大部分操作都封裝到輸入流裏了,所以在學習這個之前建議先去學習PipedInputSream

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章