(最近刚来到简书平台,以前在CSDN上写的一些东西,也在逐渐的移到这儿来,有些篇幅是很早的时候写下的,因此可能会看到一些内容杂乱的文章,对此深感抱歉,以下为正文)
正文
本篇要讲述的是CharArrayReader和CharArrayWriter两个类。它们两个同之前的ByteArrayInputStream和ByteArrayOutputStream和相似,两者的主要区别是前者是基于字符数组来工作的,后者是基于字节数组来创建的。
下面先说说CharArrayReader,先附上源码:
package java.io;
public class CharArrayReader extends Reader {
//用于存储从流中读取的数据
protected char buf[];
//下一个读取的字符位置
protected int pos;
//被标记的字符位置,reset时pos回到此处
protected int markedPos = 0;
//字符数组的长度
protected int count;
//初始化传入一个字符数组
public CharArrayReader(char buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
//初始化传入一个字符数组,offset为开始读取的索引,length是读取的长度
public CharArrayReader(char buf[], int offset, int length) {
if ((offset < 0) || (offset > buf.length) || (length < 0) ||
((offset + length) < 0)) {
throw new IllegalArgumentException();
}
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.markedPos = offset;
}
//判断流是否处于打开状态,因为当执行close后,buf会被置为null
private void ensureOpen() throws IOException {
if (buf == null)
throw new IOException("Stream closed");
}
//按每个字符读取,读取时首先判断流是否处于打开状态,如果下一个读取的索引位置超出数据长度,则返回-1,否则回对应的字符。
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
if (pos >= count)
return -1;
else
return buf[pos++];
}
}
//该方法是按照所传入的数组来进行读取,off为开始读取的位置,len为读取的长度
public int read(char b[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (pos >= count) {
return -1;
}
if (pos + len > count) {
len = count - pos;
}
if (len <= 0) {
return 0;
}
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
}
//跳过n字符再进行读取
public long skip(long n) throws IOException {
synchronized (lock) {
ensureOpen();
if (pos + n > count) {
n = count - pos;
}
if (n < 0) {
return 0;
}
pos += n;
return n;
}
}
//该方法用于判断是否还有刻度数据
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return (count - pos) > 0;
}
}
//判断是否支持标记功能,一直返回true
public boolean markSupported() {
return true;
}
//标记功能,将当前pos值做为标记值,传入的参数无意义
public void mark(int readAheadLimit) throws IOException {
synchronized (lock) {
ensureOpen();
markedPos = pos;
}
}
//重置当前pos值,使其返回标记的位置,mark值如果没有重置过,默认为0
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
pos = markedPos;
}
}
//流关闭时,将数据缓存置为null
public void close() {
buf = null;
}
}
从上可以看出,CharArrayReader在关闭流后,无法执行其中方法,并且其中的缓存数据将会被清空,这点和ByteArrayInputStream有着明显的区别。
下面讲讲CharArrayWriter,先贴上源码:
package java.io;
import java.util.Arrays;
public
class CharArrayWriter extends Writer {
//用于存放写入数据的临时缓存
protected char buf[];
//数据长度
protected int count;
//不带参的构造函数,默认缓存空间为32字节大小
public CharArrayWriter() {
this(32);
}
//带一个参数的构造函数,传入参数为缓存的空间大小
public CharArrayWriter(int initialSize) {
if (initialSize < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ initialSize);
}
buf = new char[initialSize];
}
//带一个参数的wirte方法,传入参数为要写入的字符,如果缓存空间不足时,缓存区会自动扩容,空间翻倍。
public void write(int c) {
synchronized (lock) {
int newcount = count + 1;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
buf[count] = (char)c;
count = newcount;
}
}
//第一个参数是要写入的字符数组,第二个参数为开始写入的位置,第三个参数是写入的长度
public void write(char c[], int off, int len) {
if ((off < 0) || (off > c.length) || (len < 0) ||
((off + len) > c.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
synchronized (lock) {
int newcount = count + len;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
System.arraycopy(c, off, buf, count, len);
count = newcount;
}
}
//第一个参数是要写入的字符串,第二个参数为开始写入的位置,第三个参数是写入的长度
public void write(String str, int off, int len) {
synchronized (lock) {
int newcount = count + len;
if (newcount > buf.length) {
buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
}
str.getChars(off, off + len, buf, count);
count = newcount;
}
}
//该方法是将缓存中的数据写人另一个流中
public void writeTo(Writer out) throws IOException {
synchronized (lock) {
out.write(buf, 0, count);
}
}
//该方法可以向流中写入传入的字符序列
public CharArrayWriter append(CharSequence csq) {
String s = (csq == null ? "null" : csq.toString());
write(s, 0, s.length());
return this;
}
//该方法可以向流中写入字符序列,第二和第三个参数决定了写入的起点和终点
public CharArrayWriter append(CharSequence csq, int start, int end) {
String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
write(s, 0, s.length());
return this;
}
//该方法可以向流中写入传入的字符,与write的区别是该方法返回了流对象
public CharArrayWriter append(char c) {
write(c);
return this;
}
//重置读取位置,将count置为0
public void reset() {
count = 0;
}
//将流中缓存区的数据以char数组的形式返回
public char toCharArray()[] {
synchronized (lock) {
return Arrays.copyOf(buf, count);
}
}
//返回数据的大小
public int size() {
return count;
}
//将流中数据已字符串的形式返回
public String toString() {
synchronized (lock) {
return new String(buf, 0, count);
}
}
//刷新流
public void flush() { }
//关闭流
public void close() { }
}
以上为本篇的全部内容。
网友评论