您的位置:首页 > 编程语言 > Java开发

Java 7之传统I/O - 字符接口 Reader和Writer

2014-01-12 08:29 435 查看
在介绍字符输入输出流之前,当然要介绍一下输入输出流的Reader和Writer接口了。先来看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
    private final int writeBufferSize = 1024;

    protected Object lock;
    protected Writer() {
        this.lock = this;
    }
    protected Writer(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }
   // ...
 }
给lock赋值的时候可以通过默认的构造函数或通过传参的构造函数,这个值主要是用来锁定一个对象实例的,以防止发生多线程问题,例如在最重要的write()方法中就使得了同步块来同步重要的功能:

/**
     * 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.
     */
    public void write(int c) throws IOException {
        synchronized (lock) {
            if (writeBuffer == null){
                writeBuffer = new char[writeBufferSize];
            }
            writeBuffer[0] = (char) c;
            write(writeBuffer, 0, 1);
        }
    }
     // Writes a portion of a string.
    public void write(String str, int off, int len) throws IOException {
        synchronized (lock) {
            char cbuf[];
            if (len <= writeBufferSize) {
                if (writeBuffer == null) {
                    writeBuffer = new char[writeBufferSize];
                }
                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);
        }
    }

由于方法不是同步的,所以在写入时可能会产生同步的问题,所以需要获取lock对象锁,然后向writeBuffer缓冲区中写入字符。还有其他的写入方法,这些方法或间接调用了如上的两个方法或由子类来覆写。由于Write类继承了Appendable接口,而这个接口中最重要的方法定义就是append(),在Write类中也给出了部分的实现,代码非常简单。剩下就是我们熟悉的Closable和Flushable接口了,但是这两个接口中定义的close()方法和flush()方法并没有在Write类中实现,需要子类覆写。

Reader类方法中最重要的就是read方法,读取的时候同样需要同步。因为如果在读取的时候进行写入时就可能造成错误,所以需要对读取和写入的同一个对象加锁。

/**
     * Attempts to read characters into the specified character buffer.
     * The buffer is used as a repository of characters as-is: the only
     * changes made are the results of a put operation. No flipping or
     * rewinding of the buffer is performed.
     */
    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;
    }

    /**
     * Reads a single character.  
     */
    public int read() throws IOException {
        char cb[] = new char[1];
        if (read(cb, 0, 1) == -1)
            return -1;
        else
            return cb[0];
    }

    /**
     * Reads characters into an array.  
     */
    public int read(char cbuf[]) throws IOException {
        return read(cbuf, 0, cbuf.length);
    }

    /**
     * Reads characters into a portion of an array.  
     */
    abstract public int read(char cbuf[], int off, int len) throws IOException;
还可以跳着读取字符,实现代码如下:

private static final int maxSkipBufferSize = 8192;/** Maximum skip-buffer size */
    private char skipBuffer[] = null;/** Skip buffer, null until allocated */

    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;
        }
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐