文档章节

【Java部分源码分析之io篇】5.Reader

gongwilliam
 gongwilliam
发布于 2017/07/27 22:27
字数 740
阅读 7
收藏 0

3 月,跳不动了?>>>

之前分析的都是字节的输入输出流,现在开始来看看字符的输入输出流。

Reader是字符输入流,与之对应的字节输入流是InputStream,后面会讲到有一个类利用字节输入流构建字符输入流,这个类就是InputStreamReader。与InputStream一样,Reader也是一个抽象类。它有一个成员变量lock,这个lock使得在这个流上的操作在多线程环境下可以安全的执行。来看一下这个成员变量。

    /**
     * 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;

接下来看一下它的两个构造方法。

    protected Reader() {
        this.lock = this;
    }
    protected Reader(Object lock) {
        if (lock == null) {
            throw new NullPointerException();
        }
        this.lock = lock;
    }

两个构造方法没什么看头,都是在给lock赋值。

接下来看一下read方法。

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

可以看到最下面的抽象read方法没有任何实现,这个read方法是留到子类中实现的,一般来说,子类中的read方法是调用的本地方法,用native定义。其他三个重载read方法都是调用最后一个read方法,第一个还比较特殊,它的参数是NIO的一个对象CharBuffer,以后我们会讲解到这个对象的。

    private static final int maxSkipBufferSize = 8192;
    private char skipBuffer[] = null;
    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;
        }
    }

接下来看一下所有流操作都会有的skip,就是在流上往前走的字符数。这里定义了一个最大跳跃字符数为8192,也就是说一次跳跃最大可以跳8192个字符。同时skip在方法体内用了synchronized来控制,在多线程环境下也是安全的。如果跳跃小于8192个字符,则返回跳跃的字符数。

    public void mark(int readAheadLimit) throws IOException {
        throw new IOException("mark() not supported");
    }
    public void reset() throws IOException {
        throw new IOException("reset() not supported");
    }

     abstract public void close() throws IOException;

上面两个方法是比较少用,mark的作用用来标记输入流的一个位置,这样调用reset之后,输入流就能再次回到标记的位置,readlimit代表只能从输入流读取的数目。

close是个抽象方法,具体实现是在子类中实现。一般来说也是调用在JVM层面实现的本地方法。

© 著作权归作者所有

gongwilliam
粉丝 2
博文 14
码字总数 12127
作品 0
深圳
私信 提问
加载中

评论(0)

泥沙砖瓦浆木匠/java-core-learning-example

感谢赞助的ta们 Java 核心系列教程,关于Java核心技术学习积累的例子,是初学者及核心技术巩固的最佳实践。 包括基础语法,OOP,字符串,集合,IO,反射,线程,网络等。 未完成模块:阿里J...

泥沙砖瓦浆木匠
2019/04/02
0
0
从1+1=2来理解Java字节码

背景 前不久《深入理解Java虚拟机》第三版发布了,赶紧买来看了看新版的内容,这本书更新了很多新版本虚拟机的内容,还对以前的部分内容进行了重构,还是值得去看的。本着复习和巩固的态度,...

木木匠
2019/12/30
6K
11
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
2018/06/21
0
0
Java 208 道面试题:Java 基础模块答案

目前市面上的面试题存在两大问题:第一,题目太旧好久没有更新了,还都停留在 2010 年之前的状态;第二,近几年 JDK 更新和发布都很快,Java 的用法也变了不少,加上 Java 技术栈也加入了很多...

王磊的博客
2019/03/05
921
0
Java NIO原理 图文分析及代码实现

Java NIO原理图文分析及代码实现 前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术...

囚兔
2015/04/29
349
1

没有更多内容

加载失败,请刷新页面

加载更多

XDR

XDR是一个库 XDR用于将任意类型的数据转化为平台无关的编码,然后传输,到了对应平台按照对应平台标准进行解析。 主要解决的是平台之间字节序的不同。主要是解决数据跨平台解析的问题。 XDR双...

鬼上身跳不过门槛
7分钟前
5
0
霍兰德职业兴趣测试与职业生涯规划

职业生涯规划这个词,相信小伙伴不会第一次听说,而且我肯定听的最多的地方,那就是大四的学堂里。名字听着很高大上,其实跟我们出游做计划差不多,只不过这个周期会很长。职业生涯规划里我们...

蛤蟆丸子
8分钟前
3
0
localStorage设置过期时间

场景# 浏览器端需要存储一个用户的标识和cookie一样需要过期时间,但是用的是localStorage存储。而localStorage一经存储除非手动删除是不会过期的。那就需要自己实现过期机制。网上找了几种简...

stys35
9分钟前
13
0
sessionStorage和LocalStorage区别?

两者都是浏览器提供技术,用于在浏览器端存放数据 –存数据:setItem(k,v) –取数据:getItem(k) –删数据:removeItem(k) 2. 区别: –sessionStorage会话级,浏览器打开到浏览器关闭。 –l...

安然_oschina
31分钟前
13
0
重磅消息:Google和网易集体震荡,联手让一部分游戏先出海!

4月9日参与《出海背后的技术密码》免费直播节目的伙伴,有机会获得由 Google&网易提供给大家的精美礼品。同时,今天文章后面留言点赞第一的伙伴,加文文酱(liwenzhaozhao)领取现金红包 哦!...

张晓衡
32分钟前
14
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部