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()方法都是抽象类、必须要子类实现具有自己的特色。