Reader
属性
// 用于同步针对此流的操作的对象。
protected Object lock;
构造函数
两个构造函数,使用不同的对象锁。
// 创建一个新的字符流 reader,其重要部分将同步其自身的 reader。
protected Reader() {
this.lock = this;
}
// 创建一个新的字符流 reader,其重要部分将同步给定的对象。
protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
方法
read(char cbuf[], int off, int len)
将字符读入缓冲数组 cbuf 中,从 off 下标开始存放,共 len 个字符。
abstract public int read(char cbuf[], int off, int len) throws IOException;
read()
读取单个字符。
public int read() throws IOException {
char cb[] = new char[1];
if (read(cb, 0, 1) == -1)
return -1;
else
return cb[0];
}
read(char cbuf[])
调用上边的 read 方法,从下标 0 处开始存入。
public int read(char cbuf[]) throws IOException {
return read(cbuf, 0, cbuf.length);
}
read(java.nio.CharBuffer 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;
}
skip(long n)
跳过字符。
// 最大可跳过缓冲字符的值8192
private static final int maxSkipBufferSize = 8192;
// 跳过的字符数组
private char skipBuffer[] = null;
public long skip(long n) throws IOException {
if (n < 0L)
// 跳过的字符数不能为负
throw new IllegalArgumentException("skip value is negative");
// 跳过的字符数量nn,取需求n和最大可跳过之间的较小值
int nn = (int) Math.min(n, maxSkipBufferSize);
// 同步对象锁
synchronized (lock) {
// 如果跳过数组为空或者长度小于目标跳过的数量nn,重建跳过数组长度为nn
if ((skipBuffer == null) || (skipBuffer.length < nn))
skipBuffer = new char[nn];
long r = n;
// 如果正常情况下,跳过n个,r最终是为0的
// 如果遇到末尾没有那么多字符可以跳过,那么r就是剩余不能跳过的,实际跳过n-r个
while (r > 0) {
int nc = read(skipBuffer, 0, (int)Math.min(r, nn));
if (nc == -1)
break;
r -= nc;
}
return n - r;
}
}
ready()
判断是否准备读取此流。
public boolean ready() throws IOException {
return false;
}
mark/reset
不支持 mark 和 reset 。
public boolean markSupported() {
return false;
}
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark() not supported");
}
public void reset() throws IOException {
throw new IOException("reset() not supported");
}
close()
关闭该流并释放与之关联的所有资源。在关闭该流后,再调用 read()、ready()、mark()、reset() 或 skip() 将抛出 IOException。关闭已经关闭了的流无效。
abstract public void close() throws IOException;
Writer
写入字符流的抽象类。
属性
// 临时的字符数组保存写入的字符
private char[] writeBuffer;
// 临时字符数组的大小1024
private static final int WRITE_BUFFER_SIZE = 1024;
// 用于同步针对此流的操作的对象
protected Object lock;
构造函数
和 Reader 的两个构造函数类似,两个构造函数区别在于用什么对象锁,自身还是其他对象。
protected Writer() {
this.lock = this;
}
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
方法
write(char cbuf[], int off, int len)
将字符数组 cbuf 中的字符写入输出流,从下标 off 开始,共 len 个字符。
abstract public void write(char cbuf[], int off, int len) throws IOException;
write(int c)
写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
// 字符2个字节,int是4个字节丢弃高位的2个,保留低位2个存入临时字符数组
writeBuffer[0] = (char) c;
// 调用上边的write方法,写进输出流1个字符
write(writeBuffer, 0, 1);
}
}
write(char cbuf[])
字符数组 cbuf 中写入输出流,调用上边的 write 方法。
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
write(String str, int off, int len)
字符串写入输出流。
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
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从off开始共len个字符存入cbuf字符数组中
str.getChars(off, (off + len), cbuf, 0);
// cbuf从0下标开始len个字符写进输出流
write(cbuf, 0, len);
}
}
write(String str)
public void write(String str) throws IOException {
// 调用上边的write方法
write(str, 0, str.length());
}
append(CharSequence csq)
将指定字符序列添加到此 writer。
public Writer append(CharSequence csq) throws IOException {
if (csq == null)
write("null");
else
write(csq.toString());
return this;
}
append(CharSequence csq, int start, int end)
将指定字符序列的子序列添加到此 writer
public Writer append(CharSequence csq, int start, int end) throws IOException {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
}
append(char c)
将指定字符添加到此 writer。
public Writer append(char c) throws IOException {
write(c);
return this;
}
flush()
刷新该流的缓冲。如果该流已保存缓冲区中各种 write() 方法的所有字符,则立即将它们写入预期目标。然后,如果该目标是另一个字符或字节流,则将其刷新。因此,一次 flush() 调用将刷新 Writer 和 OutputStream 链中的所有缓冲区。
abstract public void flush() throws IOException;
close()
关闭此流,但要先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。关闭以前关闭的流无效。
abstract public void close() throws IOException;