Java基础知识之StringReader流的使用
作者:咕噜是个大胖子
这篇文章主要介绍了Java基础知识之StringReader流的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
Java StringReader流的使用
一、StringReader流定义
API说明:字符串输入流、其本质就是字符串
二、StringReader的实例域
//流对象 private String str; //流的长度 private int length; //流的当前位置,下个字符的索引 private int next = 0; //流的标记位置 private int mark = 0;
三、StringReader流构造函数
/** * 利用字符串创建字符输入流 */ public StringReader(String s) { this.str = s; this.length = s.length(); }
四、StringReader流的API
1)read()
:从流中读取单个字符,若到文件末尾则返回-1
/** * 从流中读取单个字符,若到文件末尾则返回-1 */ public int read() throws IOException { synchronized (lock) { ensureOpen(); if (next >= length) return -1; return str.charAt(next++); } }
2)read(char cbuf[], int off, int len)
:读取最多len个字节到目标数组中,从目标数组的下标off开始存储,返回实际读取的字节数
/** * 读取最多len个字节到目标数组中,从目标数组的下标off开始存储,返回实际读取的字节数 * @exception IOException If an I/O error occurs */ 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; } }
3)close()
:关闭流无效,关闭后调用该类其它方法会报异常
/** * 关闭流无效,关闭后调用该类其它方法会报异常 */ public void close() { str = null; }
五、StringReader流的作用
暂未使用故未知晓,故先了解功能
StringReader分析
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; } }
注: 正数往前跳,负数往后跳
3. 测试代码
//访问字符串 StringReader import java.io.IOException; import java.io.StringReader; public class StringReader_work { public static void StringReader() { String str = "今天外面真的冷啊果然应该点外的"; try { //1. 构造方法 传入字符串 StringReader stringReader = new StringReader(str); //2. int read() 读操作,读取一个字符 (将String字符串操作 适配成 Reader字符操作 对外提供服务) // int read=stringReader.read(); // System.out.println((char) read); //int read(char cbuf[]) throws IOException 批量读 char[] chars = new char[3]; int read1=stringReader.read(chars); System.out.println(new String(chars,0,3)); //int read(char cbuf[], int off, int len) 批量读 // char[] chars1 = new char[3]; // int read2=stringReader.read(chars1,0,3); // System.out.println(new String(chars1,0,3)); // boolean ready() 判断数据源是否存在 stringReader.ready(); //3. markSupported() 是否支持标记 FileInputStream和FileReader 都不支持 System.out.println("是否支持标记:"+stringReader.markSupported()); // void mark(int readAheadLimit) throws IOException 标记 //TODO: 测试发现并未从标记位置读,依旧是接着原先next所指位置读数据 stringReader.mark(5); char[] chars2=new char[3]; int read3 = stringReader.read(chars2,0,3); System.out.println("mark标记后读三个数:"+new String(chars2,0,3)); //TODO:mark使用并不相当于指针 --> 和RandomAccessFile的seek操作不是一个性质 // void reset() throws IOException 重置指针 // 单独使用 reset() 方法 stringReader.reset(); char[] chars3=new char[3]; int read4 = stringReader.read(chars3,0,3); System.out.println("单独使用reset()方法:"+new String(chars3,0,3)); // mark()方法 与 reset()方法 结合使用 stringReader.mark(2); stringReader.reset(); char[] chars4=new char[3]; int read5 = stringReader.read(chars4,0,3); System.out.println("mark()与reset()结合使用:"+new String(chars4,0,3)); // long skip(long ns) throws IOException 跳过流中指定数量的字符 返回跳过的字符数 stringReader.skip(2); //正数往前跳 // stringReader.skip(-2); //负数往后跳 char[] chars5=new char[3]; int read6 = stringReader.read(chars5,0,3); System.out.println("向前跳两个字符:"+new String(chars5,0,3)); //关闭流 stringReader.close(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { StringReader(); } }
运行结果
读取前三个字符:今天外
是否支持标记:true
mark标记后读三个数:面真的
单独使用reset()方法:面真的
mark()与reset()结合使用:冷啊果
向前跳两个字符:该点外
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。