Java_io体系之Writer、Reader简介、走进源码――12(二)

2014-11-24 08:05:00 · 作者: · 浏览: 2
ad(char[] cbuf, int off, int len); 抽象类:将字符读取到下标冲off开始、len个后续位置的cbuf中。 long skip(long n); 从剩余有效字符中跳过n个

3、源码分析

package com.chy.io.core;

import java.io.Closeable;
import java.io.IOException;


/**
 * Reader:字符输入流、本身是抽象类、为所有字符输入流类提供一个标准、和基本方法及简单实现、与InputStream相比、多实现一个Readble接口、
 * 支持将字符读取到指定的缓存字符数组中。要求子类重写read(char[] cbuf, int off, int len)、close()、这两个方法、一般子类都会重写Reader提供的方法
 * 或者部分方法、也可能添加新的方法来体现自己的特色。与InputStream的本质区别就是操作单位不同、由字节变为字符。
 */

public abstract class Reader implements Readable, Closeable {
    /**
     * 用于同步针对此流的操作的对象。
     */
    protected Object lock;

    /**
     * 创建一个新的字符流 reader,其重要部分将同步其自身的 reader。
     */
    protected Reader() {
    	this.lock = this;
    }

    /**
     * 创建一个新的字符流 reader,其重要部分将同步给定的对象。
     */
    protected Reader(Object lock) {
		if (lock == null) {
		    throw new NullPointerException();
		}
		this.lock = lock;
    }

    /**
     * 将输入流管道中的target.length个字节读取到指定的缓存字符数组target中、返回实际存放到target中的字符数。
     */
    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;
    }

    /**
     * 读取一个字符并返回
     */
    public int read() throws IOException {
		char cb[] = new char[1];
		if (read(cb, 0, 1) == -1)
		    return -1;
		else
		    return cb[0];
    }

    /**
     * 将字符读取到cbuf中、返回实际读取到的字符数。
     */
    public int read(char cbuf[]) throws IOException {
    	return read(cbuf, 0, cbuf.length);
    }

    /**
     * 抽象类:将字符读取到下标冲off开始、len个后续位置的cbuf中。
     */
    abstract public int read(char cbuf[], int off, int len) throws IOException;

    /** 最大允许跳过字符数 */
    private static final int maxSkipBufferSize = 8192;

    /** 用于skip方法临时存放字符 */
    private char skipBuffer[] = null;

    /**
     * 从剩余有效字符中跳过n个
     */
    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;
		}
    }

    /** 检测此流是否可读*/
    public boolean ready() throws IOException {
    	return false;
    }

    /** 检测此流是否支持标记*/
    public boolean markSupported() {
    	return false;
    }

    /** 标记此流、与reset()结合使用*/
    public void mark(int readAheadLimit) throws IOException {
    	throw new IOException("mark() not supported");
    }

    /** 将流的读取位置重置到最后一次调用mark方法时的位置*/
    public void reset() throws IOException {
    	throw new IOException("reset() not supported");
    }

    /** 关闭此流、释放与此流有关的所有资源*/
     abstract public void close() throws IOException;

}


总结:

通过两组对比来观察一下相同与区别

OutputStream/InputStream VS Writer/Reader

相同:

都是抽象类、为所有子类提供标准、和基本的方法及简单实现、关键方法是抽象方法、要子类根据自己的特色去实现

其他读写方法都是以这个关键方法为核心实现的、Reader/InputStream都继承了closeable接口。

Writer/OutputStream都继承了Closeable,Flushable

区别:

本质区别――操作的对象不同。字节流针对的是字节、字符流针对的是字符

Reader相比与InputStream多实现了一个Readable接口、用于提供一个可以将字符写入到指定缓存数组的方法

同时两者用于实现读取的关键抽象方法、reader.read(char[] cbuf,int off, int len)、inputStream.read();

一个是针对字符数组、一个是针对单个字节、其他的读取方法都是以这两个方法为核心的。

还有一个区别就是两者的close()方法类型不一样、Reader的close方法是抽象类、必须要子类重写、

InputStream.close不是抽象类、子类可以重写、也可不重写。

Writer相比与OutputStream多实现了一个Appendable接口、用于向此流中追加字符。两者用于读取的关键方法也是一个针对字符数组、一个针对字节

并且Writer的close()、flush()方法都是抽象类、必须要子类实现具有自己的特色。


更多IO内容:java_io 体系之目录