IO流分类图
访问字符串
StringReader是字符输入流,Reader的子类,从一个String中读取,所以需要一个String ,通过构造方法传递
StringWriter是字符输出流,Writer的子类,写入到一个String中去,所以它内部提供了一个StringBuffer中用来保存数据
StringReader
1. 属性和构造方法
private String str;
private int length;
private int next = 0;
private int mark = 0;
public StringReader(String s) { //传入字符串
this.str = s;
this.length = s.length();
}
str :指向这个字符串
length :为字符串长度
next :为读取元素的下标索引
mark :为标记点
2. 基本方法
- read()方法
//读取一个字符
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
if (next >= length)
return -1;
return str.charAt(next++);
}
}
注::从中可看出StringReader 将String字符串操作 适配成 Reader字符操作 对外提供服务 —> StringReader是一个适配器类
//批量读取
public int read(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (next >= length)
return -1;
int n = Math.min(length - next, len);
str.getChars(next, next + n, cbuf, off);
next += n;
return n;
}
}
- 标记相关方法
//判断是否支持标记
public boolean markSupported() {
return true;
}
注: FileInputStream 和 FileReader 都不支持标记
//标记
public void mark(int readAheadLimit) throws IOException {
if (readAheadLimit < 0){
throw new IllegalArgumentException("Read-ahead limit < 0");
}
synchronized (lock) {
ensureOpen();
mark = next;
}
}
注: mark的使用并不相当于指针,需要和reset()方法一起使用 --> 和RandomAccessFile的seek操作不是一个性质
//重置指针
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
next = mark;
}
}
注: 将mark标记赋给next,reset()和mark()两个方法配合使用
//跳过流中指定数量的字符 返回跳过的字符数
public long skip(long ns) throws IOException {
synchronized (lock) {
ensureOpen();
if (next >= length)
return 0;
// Bound skip by beginning and end of the source
long n = Math.min(length - next, ns);
n = Math.max(-next, n);
next += n;
return n;
}
}
注: 正数往前跳,负数往后跳