zoukankan      html  css  js  c++  java
  • 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. 基本方法

    1. 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;
            }
        }

    2. 标记相关方法

        //判断是否支持标记
        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()结合使用:冷啊果
    向前跳两个字符:该点外
  • 相关阅读:
    SQL2008安装重启失败
    UML学习笔记
    强大的wget
    记录几款不错的chrome主题
    关于nginx配置的不完全总结
    关于Mac下的SSH客户端iterm2等配置
    安装配置sock5代理
    配置DNS
    复习一些编译原理
    了解CentOS及周边
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/15714969.html
Copyright © 2011-2022 走看看