目录
字段writeBuffer,WRITE_BUFFER_SIZE,lock,两个构造函数
简介
package java.io;
/**
* 用于写入字符流的抽象类。
* 子类必须实现的唯一方法是write(char[], int, int), flush()和close()。
* 然而,大多数子类会覆盖这里定义的一些方法,以提供更高的效率,额外的功能,或两者兼有。
*
* @see Writer
* @see BufferedWriter
* @see CharArrayWriter
* @see FilterWriter
* @see OutputStreamWriter
* @see FileWriter
* @see PipedWriter
* @see PrintWriter
* @see StringWriter
* @see Reader
*
* @author Mark Reinhold
* @since JDK1.1
*/
public abstract class Writer implements Appendable, Closeable, Flushable
字段writeBuffer,WRITE_BUFFER_SIZE,lock,两个构造函数
/**
* 用来保存对字符串和单个字符的写操作的临时缓冲区
*/
private char[] writeBuffer;
/**
* writeBuffer的大小,必须是>= 1
*/
private static final int WRITE_BUFFER_SIZE = 1024;
/**
* 用于同步此流上的操作的对象。
* 更重要的是,字符流对象可以使用自身以外的对象来保护临界区。
* 因此子类应该在这个字段中使用对象,而不是this或同步方法。
*/
protected Object lock;
/**
* 创建一个新的字符流写入器,其临界区将在写入器本身上同步。
*/
protected Writer() {
this.lock = this;
}
/**
* 创建一个新的字符流写入器,它的临界区将在给定对象上同步。
*
* @param lock
* Object to synchronize on
*/
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
5个write方法
/**
* 只写一个字符。
* 待写入的字符包含在给定整数值的16位低阶比特中;
* 16个高阶位被忽略。
*
* <p> 打算支持高效单字符输出的子类应该重写此方法。
*
* @param c
* int specifying a character to be written
*
* @throws IOException
* If an I/O error occurs
*/
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
// 先写入writeBuffer,再把writeBuffer写入输出流
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
}
/**
* 写入一个字符数组。
*
* @param cbuf
* Array of characters to be written
*
* @throws IOException
* If an I/O error occurs
*/
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
/**
* 写入一个字符数组的一部分。
*
* @param cbuf
* Array of characters
*
* @param off
* Offset from which to start writing characters
*
* @param len
* Number of characters to write
*
* @throws IOException
* If an I/O error occurs
*/
abstract public void write(char cbuf[], int off, int len) throws IOException;
/**
* 写入一个字符串。
*
* @param str
* String to be written
*
* @throws IOException
* If an I/O error occurs
*/
public void write(String str) throws IOException {
write(str, 0, str.length());
}
/**
* 写入一个字符串的一部分。
*
* @param str
* A String
*
* @param off
* Offset from which to start writing characters
*
* @param len
* Number of characters to write
*
* @throws IndexOutOfBoundsException
* If <tt>off</tt> is negative, or <tt>len</tt> is negative,
* or <tt>off+len</tt> is negative or greater than the length
* of the given string
*
* @throws IOException
* If an I/O error occurs
*/
public void write(String str, int off, int len) throws IOException {
synchronized (lock) {
char cbuf[];
// 如果len小于等于WRITE_BUFFER_SIZE,cbuf为writeBuffer
// 如果大于,建立一个len长度的数组,赋值给cbuf(注意:没有赋值给writeBuffer!)
if (len <= WRITE_BUFFER_SIZE) {
if (writeBuffer == null) {
writeBuffer = new char[WRITE_BUFFER_SIZE];
}
cbuf = writeBuffer;
} else { // 不要永久分配非常大的缓存
cbuf = new char[len];
}
// str的元素复制到cbuf,然后cbuf写入输出流
str.getChars(off, (off + len), cbuf, 0);
write(cbuf, 0, len);
}
}
3个append方法,flush方法,close方法
/**
* 向写入器追加指定的字符序列。
*
* <p> 对out.append(csq)表单的这个方法的调用行为与调用的方式完全相同
*
* <pre>
* out.write(csq.toString()) </pre>
*
* <p> 根据字符序列csq的toString规范,整个序列可能不会被附加。
* 例如,调用字符缓冲区的toString方法将返回一个子序列,其内容取决于缓冲区的位置和限制。
*
* @param csq
* The character sequence to append. If <tt>csq</tt> is
* <tt>null</tt>, then the four characters <tt>"null"</tt> are
* appended to this writer.
*
* @return This writer
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.5
*/
public Writer append(CharSequence csq) throws IOException {
if (csq == null)
write("null");
else
write(csq.toString());
return this;
}
/**
* 向写入器追加指定字符序列的子序列。
*
* <p> 当csq不是null时,调用此方法的形式out.append(csq, start,end)与调用的方式完全相同
*
* <pre>
* out.write(csq.subSequence(start, end).toString()) </pre>
*
* @param csq
* The character sequence from which a subsequence will be
* appended. If <tt>csq</tt> is <tt>null</tt>, then characters
* will be appended as if <tt>csq</tt> contained the four
* characters <tt>"null"</tt>.
*
* @param start
* The index of the first character in the subsequence
*
* @param end
* The index of the character following the last character in the
* subsequence
*
* @return This writer
*
* @throws IndexOutOfBoundsException
* If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
* is greater than <tt>end</tt>, or <tt>end</tt> is greater than
* <tt>csq.length()</tt>
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.5
*/
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;
}
/**
* 向写入器追加单个字符的子序列。
*
* <p> 当csq不是null时,调用此方法的形式out.append(c)与调用的方式完全相同
*
* <pre>
* out.write(c) </pre>
*
* @param c
* The 16-bit character to append
*
* @return This writer
*
* @throws IOException
* If an I/O error occurs
*
* @since 1.5
*/
public Writer append(char c) throws IOException {
write(c);
return this;
}
/**
* 刷新流。
* 如果流在缓冲区中保存了各种write()方法中的任何字符,请立即将它们写入预期的目的地。
* 然后,如果目的地是另一个字符或字节流,刷新它。
* 因此,一次flush()调用将刷新写入器和输出流链中的所有缓冲区。
*
* <p> 如果这个流的目的是底层操作系统提供的抽象,例如文件,
* 那么刷新流只能保证先前写入到流的字节被传递给操作系统进行写入;
* 它不能保证它们确实被写入物理设备,如磁盘驱动器。
*
* @throws IOException
* If an I/O error occurs
*/
abstract public void flush() throws IOException;
/**
* 关闭流,首先flush。
* 一旦流被关闭,进一步的write()或flush()调用将导致抛出IOException。
* 关闭以前关闭的流没有任何效果。
*
* @throws IOException
* If an I/O error occurs
*/
abstract public void close() throws IOException;