Java-IO之字符输入输出流(Reader和Writer)

来源:互联网 发布:软件开发可行性报告 编辑:程序博客网 时间:2024/05/16 06:26

以字符为单位的输入流的公共父类是Reader:

以字符为单位的输出流的超类是Writer:

基于JDK8的Reader的源码:

public abstract class Reader implements Readable, Closeable {    /**     * The object used to synchronize operations on this stream.  For     * efficiency, a character-stream object may use an object other than     * itself to protect critical sections.  A subclass should therefore use     * the object in this field rather than <tt>this</tt> or a synchronized     * method.     */    protected Object lock;    /**     * Creates a new character-stream reader whose critical sections will     * synchronize on the reader itself.     */    protected Reader() {        this.lock = this;    }    /**     * Creates a new character-stream reader whose critical sections will     * synchronize on the given object.     *     * @param lock  The Object to synchronize on.     */    protected Reader(Object lock) {        if (lock == null) {            throw new NullPointerException();        }        this.lock = lock;    }    //尝试读字符进字符缓冲    public int read(java.nio.CharBuffer target) throws IOException {        int len = target.remaining();        char[] cbuf = new char[len];        int n = read(cbuf, 0, len);        if (n > 0)            target.put(cbuf, 0, n);        return n;    }    //读单个字符,方法会阻塞直到字符是有效,出现IO错误,或者流完毕    public int read() throws IOException {        char cb[] = new char[1];        if (read(cb, 0, 1) == -1)            return -1;        else            return cb[0];    }    //读字符数组    public int read(char cbuf[]) throws IOException {        return read(cbuf, 0, cbuf.length);    }    abstract public int read(char cbuf[], int off, int len) throws IOException;    /** Maximum skip-buffer size */    private static final int maxSkipBufferSize = 8192;    /** Skip buffer, null until allocated */    private char skipBuffer[] = null;    /**     * Skips characters.  This method will block until some characters are     * available, an I/O error occurs, or the end of the stream is reached.     *     * @param  n  The number of characters to skip     *     * @return    The number of characters actually skipped     *     * @exception  IllegalArgumentException  If <code>n</code> is negative.     * @exception  IOException  If an I/O error occurs     */    public long skip(long n) throws IOException {        if (n < 0L)            throw new IllegalArgumentException("skip value is negative");        int nn = (int) Math.min(n, maxSkipBufferSize);        synchronized (lock) {            if ((skipBuffer == null) || (skipBuffer.length < nn))                skipBuffer = new char[nn];            long r = n;            while (r > 0) {                int nc = read(skipBuffer, 0, (int)Math.min(r, nn));                if (nc == -1)                    break;                r -= nc;            }            return n - r;        }    }    /**     * Tells whether this stream is ready to be read.     *     */    //是否准备好去读    public boolean ready() throws IOException {        return false;    }    //不支持标记    public boolean markSupported() {        return false;    }    //会抛出错误    public void mark(int readAheadLimit) throws IOException {        throw new IOException("mark() not supported");    }    //不支持reset,会抛出错误    public void reset() throws IOException {        throw new IOException("reset() not supported");    }    //关闭资源    abstract public void close() throws IOException;}
基于JDK8的Writer源码:

public abstract class Writer implements Appendable, Closeable, Flushable {    /**     * Temporary buffer used to hold writes of strings and single characters     */    //写缓冲数组    private char[] writeBuffer;    /**     * Size of writeBuffer, must be >= 1     */    //写缓冲数组默认大小是1024    private static final int WRITE_BUFFER_SIZE = 1024;    /**     * The object used to synchronize operations on this stream.  For     * efficiency, a character-stream object may use an object other than     * itself to protect critical sections.  A subclass should therefore use     * the object in this field rather than <tt>this</tt> or a synchronized     * method.     */    //对象    protected Object lock;    /**     * Creates a new character-stream writer whose critical sections will     * synchronize on the writer itself.     */    //    protected Writer() {        this.lock = this;    }    /**     * Creates a new character-stream writer whose critical sections will     * synchronize on the given object.     *     * @param  lock     *         Object to synchronize on     */    protected Writer(Object lock) {        if (lock == null) {            throw new NullPointerException();        }        this.lock = lock;    }    /**     * Writes a single character.  The character to be written is contained in     * the 16 low-order bits of the given integer value; the 16 high-order bits     * are ignored.     *     * <p> Subclasses that intend to support efficient single-character output     * should override this method.     *     * @param  c     *         int specifying a character to be written     *     * @throws  IOException     *          If an I/O error occurs     */    //写一个字符    public void write(int c) throws IOException {        synchronized (lock) {            if (writeBuffer == null){                writeBuffer = new char[WRITE_BUFFER_SIZE];            }            writeBuffer[0] = (char) c;            write(writeBuffer, 0, 1);        }    }    /**     * Writes an array of characters.     *     * @param  cbuf     *         Array of characters to be written     *     * @throws  IOException     *          If an I/O error occurs     */    //写一个字符数组    public void write(char cbuf[]) throws IOException {        write(cbuf, 0, cbuf.length);    }    abstract public void write(char cbuf[], int off, int len) throws IOException;    //写一个String    public void write(String str) throws IOException {        write(str, 0, str.length());    }    //写一个字符串的一部分    public void write(String str, int off, int len) throws IOException {        synchronized (lock) {            char cbuf[];            if (len <= WRITE_BUFFER_SIZE) {                if (writeBuffer == null) {                    writeBuffer = new char[WRITE_BUFFER_SIZE];                }                cbuf = writeBuffer;            } else {    // Don't permanently allocate very large buffers.                cbuf = new char[len];            }            str.getChars(off, (off + len), cbuf, 0);            write(cbuf, 0, len);        }    }    //追加    public Writer append(CharSequence csq) throws IOException {        if (csq == null)            write("null");        else            write(csq.toString());        return this;    }    /**     * Appends a subsequence of the specified character sequence to this writer.     * <tt>Appendable</tt>.     *     * <p> An invocation of this method of the form <tt>out.append(csq, start,     * end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the     * same way as the invocation     *     * <pre>     *     out.write(csq.subSequence(start, end).toString()) </pre>     *     * @param  csq     *         The character sequence from which a subsequence will be     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters     *         will be appended as if <tt>csq</tt> contained the four     *         characters <tt>"null"</tt>.     *     * @param  start     *         The index of the first character in the subsequence     *     * @param  end     *         The index of the character following the last character in the     *         subsequence     *     * @return  This writer     *     * @throws  IndexOutOfBoundsException     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than     *          <tt>csq.length()</tt>     *     * @throws  IOException     *          If an I/O error occurs     *     * @since  1.5     */    public Writer append(CharSequence csq, int start, int end) throws IOException {        CharSequence cs = (csq == null ? "null" : csq);        write(cs.subSequence(start, end).toString());        return this;    }    /**     * Appends the specified character to this writer.     *     * <p> An invocation of this method of the form <tt>out.append(c)</tt>     * behaves in exactly the same way as the invocation     *     * <pre>     *     out.write(c) </pre>     *     * @param  c     *         The 16-bit character to append     *     * @return  This writer     *     * @throws  IOException     *          If an I/O error occurs     *     * @since 1.5     */    public Writer append(char c) throws IOException {        write(c);        return this;    }    /**     * Flushes the stream.  If the stream has saved any characters from the     * various write() methods in a buffer, write them immediately to their     * intended destination.  Then, if that destination is another character or     * byte stream, flush it.  Thus one flush() invocation will flush all the     * buffers in a chain of Writers and OutputStreams.     *     * <p> If the intended destination of this stream is an abstraction provided     * by the underlying operating system, for example a file, then flushing the     * stream guarantees only that bytes previously written to the stream are     * passed to the operating system for writing; it does not guarantee that     * they are actually written to a physical device such as a disk drive.     *     * @throws  IOException     *          If an I/O error occurs     */    abstract public void flush() throws IOException;    /**     * Closes the stream, flushing it first. Once the stream has been closed,     * further write() or flush() invocations will cause an IOException to be     * thrown. Closing a previously closed stream has no effect.     *     * @throws  IOException     *          If an I/O error occurs     */    abstract public void close() throws IOException;}



0 0