The PipedReader class in the IO package of Java Daily (44)

This class has no imported package

Inherited from the Reader class


The class header annotation for this class is as follows: (the most concise I've seen

 Piped character-input streams.

The gist is as follows:

pipe character input stream



This class contains the following member variables:

Corresponds to the output stream flag bit (whether it is closed or not

boolean closedByWriter = false;

Corresponding to the read stream close flag (that is, myself, I feel that volaile should also be added here

boolean closedByReader = false;

Connection Status

boolean connected = false;

read thread

Thread readSide;

write thread

Thread writeSide;

Default buffer size

private static final int DEFAULT_PIPE_SIZE = 1024;

buffer

char buffer[];

write offset

int in = -1;

read offset

int out = 0;


This class contains the following member methods:

Constructor (link with given writeout pipe, use default size buffer

public PipedReader(PipedWriter src) throws IOException {
    this(src, DEFAULT_PIPE_SIZE);
}

Constructor (connect to the given writeout pipe, using a buffer of the specified size

public PipedReader(PipedWriter src, int pipeSize) throws IOException {
    initPipe(pipeSize);
    connect(src);
}

Default constructor (no link yet, default size

public PipedReader() {
    initPipe(DEFAULT_PIPE_SIZE);
}

Constructor (no link yet, given size

public PipedReader(int pipeSize) {
    initPipe(pipeSize);
}

pipe initialization (initialize buffer

private void initPipe(int pipeSize) {
    if (pipeSize <= 0) {
        throw new IllegalArgumentException("Pipe size <= 0");
    }
    buffer = new char[pipeSize];
}

connecting pipes

public void connect(PipedWriter src) throws IOException {
    src.connect(this);
}

Receive single character data into pipe

synchronized void receive(int c) throws IOException {
    if (!connected) {//检查连接状态
        throw new IOException("Pipe not connected");
    } else if (closedByWriter || closedByReader) {//检测是否有一段关闭
        throw new IOException("Pipe closed");
    } else if (readSide != null && !readSide.isAlive()) {//检测读取线程活动性
        throw new IOException("Read end dead");
    }

    writeSide = Thread.currentThread();
    while (in == out) {//当前缓冲区已满,暂时无法写入
        if ((readSide != null) && !readSide.isAlive()) {
            throw new IOException("Pipe broken");
        }
        /* full: kick any waiting readers */
        notifyAll();//唤醒所有挂起线程(读取线程
        try {
            wait(1000);//挂写入线程
        } catch (InterruptedException ex) {
            throw new java.io.InterruptedIOException();
        }
    }
    if (in < 0) {//缓冲为空
        in = 0;
        out = 0;
    }
    buffer[in++] = (char) c;//存写入数据
    if (in >= buffer.length) {//循环数组修改偏移量
        in = 0;
    }
}

接收字符数组(对上一个函数的循环调用

synchronized void receive(char c[], int off, int len)  throws IOException {
    while (--len >= 0) {
        receive(c[off++]);
    }
}

当写入端数据全部传输完后,唤醒读取线程,关闭管道

synchronized void receivedLast() {
    closedByWriter = true;
    notifyAll();//唤醒所有读取线程
}

读取字符数据

public synchronized int read()  throws IOException {
    if (!connected) {//管道连接状态
        throw new IOException("Pipe not connected");
    } else if (closedByReader) {//Reader端是否关闭
        throw new IOException("Pipe closed");
    } else if (writeSide != null && !writeSide.isAlive()//检测现在是否有程序在写入
               && !closedByWriter && (in < 0)) {
        throw new IOException("Write end dead");
    }

    readSide = Thread.currentThread();//写入线程绑定
    int trials = 2;//两次机会
    while (in < 0) {//当前为空
        if (closedByWriter) {//且写入端已关闭
            /* closed by writer, return EOF */
            return -1;
        }
        if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {
            throw new IOException("Pipe broken");
        }
        /* might be a writer waiting */
        notifyAll();//唤醒所有线程(写线程
        try {
            wait(1000);//睡读取线程
        } catch (InterruptedException ex) {
            throw new java.io.InterruptedIOException();
        }
    }
    int ret = buffer[out++];//读取数据
    if (out >= buffer.length) {
        out = 0;
    }
    if (in == out) {//读取完毕,缓冲区为空
        /* now empty */
        in = -1;
    }
    return ret;//返回字符的UTF-8
}

读取出字符数组

public synchronized int read(char cbuf[], int off, int len)  throws IOException {
    if (!connected) {
        throw new IOException("Pipe not connected");
    } else if (closedByReader) {
        throw new IOException("Pipe closed");
    } else if (writeSide != null && !writeSide.isAlive()
               && !closedByWriter && (in < 0)) {
        throw new IOException("Write end dead");
    }

    if ((off < 0) || (off > cbuf.length) || (len < 0) ||//下表有效性检查
        ((off + len) > cbuf.length) || ((off + len) < 0)) {
        throw new IndexOutOfBoundsException();
    } else if (len == 0) {
        return 0;
    }

    /* possibly wait on the first character */
    int c = read();//调用上个函数获得数据
    if (c < 0) {//判定缓冲区是否为空
        return -1;
    }
    cbuf[off] =  (char)c;//写入数组
    int rlen = 1;//实际读取出的长度
    while ((in >= 0) && (--len > 0)) {//循环读取
        cbuf[off + rlen] = buffer[out++];
        rlen++;
        if (out >= buffer.length) {
            out = 0;
        }
        if (in == out) {
            /* now empty */
            in = -1;
        }
    }
    return rlen;
}

检查当前管道是否可以进行数据读取

public synchronized boolean ready() throws IOException {
    if (!connected) {
        throw new IOException("Pipe not connected");
    } else if (closedByReader) {
        throw new IOException("Pipe closed");
    } else if (writeSide != null && !writeSide.isAlive()
               && !closedByWriter && (in < 0)) {
        throw new IOException("Write end dead");
    }
    if (in < 0) {
        return false;
    } else {//管道有效且缓冲区不为空
        return true;
    }
}

关闭当前管道

public void close()  throws IOException {
    in = -1;//清空缓冲区
    closedByReader = true;//reader端关闭
}


该类与PipedInputStream类基本一样,只是在操作的时候加入char类型的强制转码,该类一些需要注意的地方与PipedInputStream相同,如有需要请查阅。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324612420&siteId=291194637