java IO笔记(Reader/Writer)

来源:互联网 发布:网络建设服务商 编辑:程序博客网 时间:2024/05/16 01:18

本篇讲述的是java io中的reader和writer。跟之前讲述的InputStream和OutputStream一样为io流中的抽象父类之一,不过Reader和Writer的操作对象不再是字节而是字符了。下面也不多说,贴上源码来加深我们的理解。

Reader.java

package java.io;public abstract class Reader implements Readable, Closeable {    /**     * 声明一个Object对象,为后续方法进行同步操作时,提供同步锁     */    protected Object lock;    /**     * 一个不带参的构造方法,并将锁对象lock初始化为当前类     */    protected Reader() {        this.lock = this;    }    /**     *一个带一个参数的构造方法,传入一个Object对象,对传入参数进行安全监测后,将传入参数赋值给锁对象lock     */    protected Reader(Object lock) {        if (lock == null) {            throw new NullPointerException();        }        this.lock = lock;    }    /**     * 一个带一个参数的read方法,传入的参数为一个字符缓冲区对象,从流中读取字符数据放置与字符缓冲区中,最终返回实际存储到字符缓冲区的字符的数量     */    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;    }    /**     *一个不带参数的read方法,每次读取一个字符,如果没有成功读取到字符数据返回-1,否则返回读取到的字符     */    public int read() throws IOException {        char cb[] = new char[1];        if (read(cb, 0, 1) == -1)            return -1;        else            return cb[0];    }    /**     * 一个带一个参数的read方法,传入的参数为一个字符数组,从流中读取数据,并将数据存放入传入的字符数组中,最终返回成功读取到的字符数量     */    public int read(char cbuf[]) throws IOException {        return read(cbuf, 0, cbuf.length);    }    /**     *一个带三个参数的read方法,该方法为抽象方法,第一个参数为一个字符数组,第二个参数为数据存储开始的位置,第三个参数为数据存储使用的长度     */    abstract public int read(char cbuf[], int off, int len) throws IOException;    /**     *声明了一个静态常量,maxSkipBufferSize,将其赋值为8192,该值表明了最多能跳过的字符数     */    private static final int maxSkipBufferSize = 8192;    /**      *声明了一个字符数组,该数组用于跳过阅读     */    private char skipBuffer[] = null;    /**     * 一个带一个参数的skip方法,参数为long型,表明要跳过的长度     */    public long skip(long n) throws IOException {//对传入参数进行安全监测,如果小于0,则抛出异常        if (n < 0L)            throw new IllegalArgumentException("skip value is negative");//确定跳过的字符数量,如果n没有超过最大限定的值,则跳过n个长度,如果大于最大值,则跳过最大值的长度(maxSkipBufferSize)        int nn = (int) Math.min(n, maxSkipBufferSize);//如果skipbuffer为空或者其容量不足以满足跳跃的长度,则新建一个skipBuffer        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;        }    }    /**     * 检测当前流是否可读,此处永远返回false     */    public boolean ready() throws IOException {        return false;    }    /**     * 检测当前流是否支持标记功能,此处永远返回false     */    public boolean markSupported() {        return false;    }    /**     *一个带一个参数的mark方法,传入的参数为标记的位置,用于在流中进行标记,一般与reset方法一起使用     */    public void mark(int readAheadLimit) throws IOException {        throw new IOException("mark() not supported");    }    /**     *一个不带参数的reset方法,将流的读取位置重置到被mark方法标记的位置     */    public void reset() throws IOException {        throw new IOException("reset() not supported");    }    /**     * close方法用于关闭流,是一个抽象方法     */     abstract public void close() throws IOException;}

Writer.java
package java.io;public abstract class Writer implements Appendable, Closeable, Flushable {    /**     * 声明了一个字符数组,用于存放需要写出的数据     */    private char[] writeBuffer;    /**     * 定义了静态常量值 WRITE_BUFFER_SIZE,该值为存放写出数据的字符数组的初始容量,初始容量为1024     */    private static final int WRITE_BUFFER_SIZE = 1024;    /**     * 声明一个Object对象,为后续方法进行同步操作时,提供同步锁     */    protected Object lock;    /**     * 一个不带参的构造方法,并将锁对象lock初始化为当前类     */    protected Writer() {        this.lock = this;    }    /**     * 一个带有一个参数的Writer对象,传入的参数为一个Object对象,并将该值赋值给锁对象lock     */    protected Writer(Object lock) {        if (lock == null) {            throw new NullPointerException();        }        this.lock = lock;    }    /**     * 带有一个参数的write方法,传入的是一个字符的int型值,每次写出一个字符     */    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);        }    }    /**     * 带有一个参数的write方法,传入的是一个字符型数组,将传入的数组中的内容一次写出     */    public void write(char cbuf[]) throws IOException {        write(cbuf, 0, cbuf.length);    }    /**     * 一个带有三个参数的write方法,第一个参数为一个字符型数组,其中存放着需要写出的数据,第二个参数为开始写出的位置,第三个参数为需要写出的长度     *该方法为抽象方法     */    abstract public void write(char cbuf[], int off, int len) throws IOException;    /**     * 一个带有一个参数的write方法,该参数为一个要写出的字符串数据     */    public void write(String str) throws IOException {        write(str, 0, str.length());    }    /**     * 一个带有三个参数的write方法,第一个参数为要写出的字符串数据,第二个参数为开始写出的位置,第三个参数为需要写出的长度     */    public void write(String str, int off, int len) throws IOException {        synchronized (lock) {//声明了一个字符数组            char cbuf[];//如果writeBuffer没有创建过,则创建。如果写出长度<小于定义的初始容量,则wirteBuffer初始化容量为1024,如果大于,则用长度初始化其容量            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);        }    }    /**     *一个带有一个参数的append方法,传入的参数为一个CharSequence类型的数据,经过安全监测后,将其转化为String型写出,最终返回当前Writer对象     */    public Writer append(CharSequence csq) throws IOException {        if (csq == null)            write("null");        else            write(csq.toString());        return this;    }    /**     * 一个带有三个参数的append方法,第一个参数是一个CharSequence类型的数据,第二个参数为要开始添加的位置,第三个参数为结束的位置     */    public Writer append(CharSequence csq, int start, int end) throws IOException {//对传入的csq先进行安全监测,通过后,根据起始位置和结束位置截取CharSequence数据,然后写出,最终返回当前Writer对象        CharSequence cs = (csq == null ? "null" : csq);        write(cs.subSequence(start, end).toString());        return this;    }    /**     * 一个带有一个参数的append方法,传入的参数为一个char型的数据,写入一个字符,最终返回当前Writer对象     */    public Writer append(char c) throws IOException {        write(c);        return this;    }    /**     *一个抽象方法flush,该方法用于将缓存中的写入数据写出值目的处     */    abstract public void flush() throws IOException;    /**     * 关闭流     */    abstract public void close() throws IOException;}

经过上面的源码可以看出,Reader/Writer和InputStream/OutputStream是十分相死的。但是也有一定的区别,最本质的区别就是前者是对字符进行操作,后者是对字节进行操作。并且两者间有些同名方法关于是否是抽象化方法略有不同。

以上为本篇内容。

原创粉丝点击