写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率或其他功能。
类的声明
public abstract class Writer implements Appendable, Closeable, Flushable
//将要写的内容放到字符数组中
private char[] writeBuffer;
//字符数组的默认长度
private final int writeBufferSize = 1024;
// 用于同步针对此流操作的对象。为了提高效率,字符流对象可以使用其自身以外的象来保护关键部分。子类应使用此字段中的对象,而不是 this 或者同步的方法。
protected Object lock;
protected Writer() {
this.lock = this;
}
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
//把整形数字转换为字符存储在数组中,再统一用write()方法
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[writeBufferSize];
}
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
}
//写入字符串数组,只有长度的不同,这里为cbuf.length.
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
//子类要实现的方法
//并且本类中都用到了这个方法,就相当于一个方法的汇总。。所有的写都归总为写字符串数组
abstract public void write(char cbuf[], int off, int len) throws IOException;
public void write(String str) throws IOException {
write(str, 0, str.length());
}
//写字符串。。有开始位置,还有长度
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
if (len <= writeBufferSize) {
if (writeBuffer == null) {
writeBuffer = new char[writeBufferSize];
}
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);
}
}
//刷新该流的缓冲。如果该流已保存缓冲区中各种 write() 方法的所有字符,则立即将它们写入预期目标。然后,如果该目标是另一个字符或字节流,则将其刷新。因此,一次 flush() 调用将刷新 Writer 和 OutputStream 链中的所有缓冲区。
//如果此流的预期目标是由底层操作系统提供的一个抽象(如一个文件),则刷新该流只能保证将以前写入到流的字节传递给操作系统进行写入,但不保证能将这些字节实际写入到物理设备(如磁盘驱动器)。
abstract public void flush() throws IOException;
//关闭此流,但要先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。
abstract public void close() throws IOException;