Reader 源码分析

读取字符流的抽象类。子类需要重写read(char[], int, int)和close()方法。很多子类会重写该类的非抽象方法以获得更好的性能或(和)额外的功能。



public abstract class Reader implements Readable, Closeable {
// 用来在流上同步操作的对象。为了提高效率,字符流对象可以使用其自身以外的对象来保护关键部分。因此,子类应使用此字段中的对象,而不是 this 或者同步的方法。
protected Object lock;

// 其重要部分将同步其自身的reader
protected Reader() {
this.lock = this;
}

// 其重要部分将同步给定的对象
protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}

// 试图将字符读入指定的字符缓冲区。缓冲区可照原样用作字符的存储库:所做的唯一改变是 put操作的结果。不对缓冲区执行翻转或重绕操作。
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;
}

// 读取单个字符。在字符可用、发生 I/O 错误或者已到达流的末尾前,此方法一直阻塞。子类可以重写该方法提升性能
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);
}

// 将字符读入数组的某一部分。在某个输入可用、发生 I/O 错误或者到达流的末尾前,此方法一直阻塞
abstract public int read(char cbuf[], int off, int len) throws IOException;

// 最大的跳过缓冲区大小
private static final int maxSkipBufferSize = 8192;

// 跳过缓冲区
private char skipBuffer[] = null;

// 跳过字符。在一些字符可用、发生 I/O 错误或者到达流的末尾前,此方法一直阻塞。
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;
}
}

// 判断此流是否已经准备好用于读取。
// 如果保证下一个 read() 不阻塞输入,则返回 True,否则返回 false。注意,返回 false 并不保证阻塞下一次读取。
public boolean ready() throws IOException {
return false;
}

// 判断此流是否支持mark操作。默认返回false,子类要重写该实现。
public boolean markSupported() {
return false;
}

// 标记流中的当前位置。对 reset() 的后续调用将尝试将该流重新定位到此点。并不是所有的字符输入流都支持 mark() 操作。
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark() not supported");
}

// 重置该流。如果已标记该流,则尝试在该标记处重新定位该流。如果未标记该流,则以适用于特定流的某种方式尝试重置该流,例如,通过将该流重新定位到其起始点。
// 并不是所有的字符输入流都支持 reset() 操作,有些支持 reset() 而不支持 mark()。
public void reset() throws IOException {
throw new IOException("reset() not supported");
}

// 关闭该流并释放与之关联的所有系统资源。关闭该流后,再调用 read()、ready()、mark()、reset() 或 skip() 将抛出 IOException。关闭以前关闭的流无效。
abstract public void close() throws IOException;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值