Java 7の従来のI/O-文字インタフェースReaderとWriter

4337 ワード

文字入出力ストリームを紹介する前に、もちろん入出力ストリームの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バッファに文字を書き込む必要があります.上記の2つのメソッドが間接的に呼び出されたり、サブクラスによって上書きされたりする他の書き込み方法もあります.WriteクラスはAppendableインタフェースを継承するため、このインタフェースの中で最も重要な方法定義はappend()であり、Writeクラスでも一部の実装が与えられ、コードは非常に簡単である.あとはよく知られているClosableとFlushableインタフェースですが、この2つのインタフェースで定義されている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;
        }
    }