java.io.BufferedWriter API 以及源码解读

下面是java se 7 API 对于java.io.BufferedWriter 继承关系的描述。

BufferedWriter可以将文本写入字符流。它会将字符缓存,目的是提高写入字符的效率。

buffer的大小必须明确,否则将会使用默认的大小。默认的大小对于大多数情况是足够大的。

BufferedWriter提供了一个newLine()的方法,目的是用来换行。毕竟不是所有的平台都使用' '的换行方式。

一个Writer对象会将输出立即写入当前的字符流或者字节流。

通常来说,如果这个写入不是非常紧急,建议使用BufferedWriter对象包裹一个费时的Writer对象(比如,FileWriters,OutputStreamWriters)

具体例子如下:

PrintWriter out = new PrintWriter(new BufferWriter(new FileWriter("foo.out")));

上面这个例子,会将PrintWriter对象的输出缓存到文件。如果没有缓存,每次调用print()方法都会讲要输出的字符立即转换为字节,这样的话写入的效率非常不高。

————————————————————————————————————————————————————————————————————

API中已经说明了BufferedWriter可以提高写入字符流的效率。对于耗时的写入操作,使用BufferWriter对象是非常明智的选择。

下面是BufferedWriter的源码。

package java.io;

public class BufferedWriter extends Writer {

    private Writer out;

    private char cb[];
    private int nChars, nextChar;

    private static int defaultCharBufferSize = 8192;

    private String lineSeparator;

    public BufferedWriter(Writer out) {
        this(out, defaultCharBufferSize);
    }

    public BufferedWriter(Writer out, int sz) {
        super(out);
        if (sz <= 0)
            throw new IllegalArgumentException("Buffer size <= 0");
        this.out = out;
        cb = new char[sz];
        nChars = sz;
        nextChar = 0;

        lineSeparator = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("line.separator"));
    }

    private void ensureOpen() throws IOException {
        if (out == null)
            throw new IOException("Stream closed");
    }

    void flushBuffer() throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (nextChar == 0)
                return;
            out.write(cb, 0, nextChar);
            nextChar = 0;
        }
    }

    
    public void write(int c) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if (nextChar >= nChars)
                flushBuffer();
            cb[nextChar++] = (char) c;
        }
    }


    private int min(int a, int b) {
        if (a < b) return a;
        return b;
    }

   
    public void write(char cbuf[], int off, int len) throws IOException {
        synchronized (lock) {
            ensureOpen();
            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
                ((off + len) > cbuf.length) || ((off + len) < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return;
            }

            if (len >= nChars) {
                /* If the request length exceeds the size of the output buffer,
                   flush the buffer and then write the data directly.  In this
                   way buffered streams will cascade harmlessly. */
                flushBuffer();
                out.write(cbuf, off, len);
                return;
            }

            int b = off, t = off + len;
            while (b < t) {
                int d = min(nChars - nextChar, t - b);
                System.arraycopy(cbuf, b, cb, nextChar, d);
                b += d;
                nextChar += d;
                if (nextChar >= nChars)
                    flushBuffer();
            }
        }
    }

   
    public void write(String s, int off, int len) throws IOException {
        synchronized (lock) {
            ensureOpen();

            int b = off, t = off + len;
            while (b < t) {
                int d = min(nChars - nextChar, t - b);
                s.getChars(b, b + d, cb, nextChar);
                b += d;
                nextChar += d;
                if (nextChar >= nChars)
                    flushBuffer();
            }
        }
    }

   
    public void newLine() throws IOException {
        write(lineSeparator);
    }

    
    public void flush() throws IOException {
        synchronized (lock) {
            flushBuffer();
            out.flush();
        }
    }

    @SuppressWarnings("try")
    public void close() throws IOException {
        synchronized (lock) {
            if (out == null) {
                return;
            }
            try (Writer w = out) {
                flushBuffer();
            } finally {
                out = null;
                cb = null;
            }
        }
    }
}

好像没有新颖之处。。。。。应该是我道行太太太浅,看不出= =

可以看到BufferedWriter之所以叫做buffered,是因为,里面使用了一个char 类型的数组作为缓存(private char cb[];)。

写操作的时候不会立刻写入当前的字符流,而是先写入缓存区。

原文地址:https://www.cnblogs.com/cuglkb/p/6905194.html