您的位置:首页 > 编程语言 > Java开发

Java-IO之字符输入输出流(Reader和Writer)

2016-10-04 18:19 585 查看
以字符为单位的输入流的公共父类是Reader:



以字符为单位的输出流的超类是Writer:



基于JDK8的Reader的源码:

public abstract class Reader implements Readable, Closeable {

/**
* The object used to synchronize operations on this stream.  For
* efficiency, a character-stream object may use an object other than
* itself to protect critical sections.  A subclass should therefore use
* the object in this field rather than <tt>this</tt> or a synchronized
* method.
*/
protected Object lock;

/**
* Creates a new character-stream reader whose critical sections will
* synchronize on the reader itself.
*/
protected Reader() {
this.lock = this;
}

/**
* Creates a new character-stream reader whose critical sections will
* synchronize on the given object.
*
* @param lock  The Object to synchronize on.
*/
protected Reader(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}
//尝试读字符进字符缓冲
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;
}
//读单个字符,方法会阻塞直到字符是有效,出现IO错误,或者流完毕
public int read() throws IOException {
char cb[] = new char[1];
if (read(cb, 0, 1) == -1)
return -1;
else
return cb[0];
}
//读字符数组
public int read(char cbuf[]) throws IOException {
return read(cbuf, 0, cbuf.length);
}
abstract public int read(char cbuf[], int off, int len) throws IOException;

/** Maximum skip-buffer size */
private static final int maxSkipBufferSize = 8192;

/** Skip buffer, null until allocated */
private char skipBuffer[] = null;

/**
* Skips characters.  This method will block until some characters are
* available, an I/O error occurs, or the end of the stream is reached.
*
* @param  n  The number of characters to skip
*
* @return    The number of characters actually skipped
*
* @exception  IllegalArgumentException  If <code>n</code> is negative.
* @exception  IOException  If an I/O error occurs
*/
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;
}
}

/**
* Tells whether this stream is ready to be read.
*
*/
//是否准备好去读
public boolean ready() throws IOException {
return false;
}

//不支持标记
public boolean markSupported() {
return false;
}
//会抛出错误
public void mark(int readAheadLimit) throws IOException {
throw new IOException("mark() not supported");
}
//不支持reset,会抛出错误
public void reset() throws IOException {
throw new IOException("reset() not supported");
}
//关闭资源
abstract public void close() throws IOException;

}
基于JDK8的Writer源码:

public abstract class Writer implements Appendable, Closeable, Flushable {

/**
* Temporary buffer used to hold writes of strings and single characters
*/
//写缓冲数组
private char[] writeBuffer;

/**
* Size of writeBuffer, must be >= 1
*/
//写缓冲数组默认大小是1024
private static final int WRITE_BUFFER_SIZE = 1024;

/**
* The object used to synchronize operations on this stream.  For
* efficiency, a character-stream object may use an object other than
* itself to protect critical sections.  A subclass should therefore use
* the object in this field rather than <tt>this</tt> or a synchronized
* method.
*/
//对象
protected Object lock;

/**
* Creates a new character-stream writer whose critical sections will
* synchronize on the writer itself.
*/
//
protected Writer() {
this.lock = this;
}

/**
* Creates a new character-stream writer whose critical sections will
* synchronize on the given object.
*
* @param  lock
*         Object to synchronize on
*/
protected Writer(Object lock) {
if (lock == null) {
throw new NullPointerException();
}
this.lock = lock;
}

/**
* Writes a single character.  The character to be written is contained in
* the 16 low-order bits of the given integer value; the 16 high-order bits
* are ignored.
*
* <p> Subclasses that intend to support efficient single-character output
* should override this method.
*
* @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[0] = (char) c;
write(writeBuffer, 0, 1);
}
}

/**
* Writes an array of characters.
*
* @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);
}

abstract public void write(char cbuf[], int off, int len) throws IOException;
//写一个String
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 <= 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.getChars(off, (off + len), cbuf, 0);
write(cbuf, 0, len);
}
}
//追加
public Writer append(CharSequence csq) throws IOException {
if (csq == null)
write("null");
else
write(csq.toString());
return this;
}

/**
* Appends a subsequence of the specified character sequence to this writer.
* <tt>Appendable</tt>.
*
* <p> An invocation of this method of the form <tt>out.append(csq, start,
* end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the
* same way as the invocation
*
* <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;
}

/**
* Appends the specified character to this writer.
*
* <p> An invocation of this method of the form <tt>out.append(c)</tt>
* behaves in exactly the same way as the invocation
*
* <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;
}

/**
* Flushes the stream.  If the stream has saved any characters from the
* various write() methods in a buffer, write them immediately to their
* intended destination.  Then, if that destination is another character or
* byte stream, flush it.  Thus one flush() invocation will flush all the
* buffers in a chain of Writers and OutputStreams.
*
* <p> If the intended destination of this stream is an abstraction provided
* by the underlying operating system, for example a file, then flushing the
* stream guarantees only that bytes previously written to the stream are
* passed to the operating system for writing; it does not guarantee that
* they are actually written to a physical device such as a disk drive.
*
* @throws  IOException
*          If an I/O error occurs
*/
abstract public void flush() throws IOException;

/**
* Closes the stream, flushing it first. Once the stream has been closed,
* further write() or flush() invocations will cause an IOException to be
* thrown. Closing a previously closed stream has no effect.
*
* @throws  IOException
*          If an I/O error occurs
*/
abstract public void close() throws IOException;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐