zoukankan      html  css  js  c++  java
  • java IO(五):StreamDecoder补遗

    简单来说,无论你调用FileReader还是InputStreamReader的read()方法,其本质都是调用StreamDecoder的read()方法。

    而read()会去调用read0(),read0()简单来说做了两件事,一个是调用read(char cbuf[], int offset, int length),其二是决定直接返回cbuf[0]还是将cbuf[1]赋值到leftoverChar再返回cbuf[0],haveLeftoverChar为true时,直接返回leftoverChar然后将其置为false。如果调用read返回-1,则表示已经读取到文件末尾,此时该read0()也会返回-1。

    read(char cbuf[], int offset, int length):

    这个方法用来调用方法读取字符到cbuf[]中,并返回实际读取到的字符数。

    public int read(char[] var1, int var2, int var3) throws IOException {
            int var4 = var2;
            int var5 = var3;
            synchronized(this.lock) {
                this.ensureOpen();
                if (var4 >= 0 && var4 <= var1.length && var5 >= 0 && var4 + var5 <= var1.length && var4 + var5 >= 0) {
                    if (var5 == 0) {
                        return 0;
                    } else {
                        byte var7 = 0;
                        if (this.haveLeftoverChar) {
                            var1[var4] = this.leftoverChar;
                            ++var4;
                            --var5;
                            this.haveLeftoverChar = false;
                            var7 = 1;
                            if (var5 == 0 || !this.implReady()) {
                                return var7;
                            }
                        }
    
                        if (var5 == 1) {
                            int var8 = this.read0();
                            if (var8 == -1) {
                                return var7 == 0 ? -1 : var7;
                            } else {
                                var1[var4] = (char)var8;
                                return var7 + 1;
                            }
                        } else {
                            return var7 + this.implRead(var1, var4, var4 + var5);
                        }
                    }
                } else {
                    throw new IndexOutOfBoundsException();
                }
            }
        }

    由于在read0()中是这么调用read的:

    int var3 = this.read(var2, 0, 2);

    且调用前已经判断了haveLeftOverChar并当其为true时会将其置成false,所以此方法在被read0()调用时本质是调用implRead():

    int implRead(char[] var1, int var2, int var3) throws IOException {
            assert var3 - var2 > 1;
    
            CharBuffer var4 = CharBuffer.wrap(var1, var2, var3 - var2);
            if (var4.position() != 0) {
                var4 = var4.slice();
            }
    
            boolean var5 = false;
    
            while(true) {
                CoderResult var6 = this.decoder.decode(this.bb, var4, var5);
                if (var6.isUnderflow()) {
                    if (var5 || !var4.hasRemaining() || var4.position() > 0 && !this.inReady()) {
                        break;
                    }
    
                    int var7 = this.readBytes();
                    if (var7 < 0) {
                        var5 = true;
                        if (var4.position() == 0 && !this.bb.hasRemaining()) {
                            break;
                        }
    
                        this.decoder.reset();
                    }
                } else {
                    if (var6.isOverflow()) {
                        assert var4.position() > 0;
                        break;
                    }
    
                    var6.throwException();
                }
            }
    
            if (var5) {
                this.decoder.reset();
            }
    
            if (var4.position() == 0) {
                if (var5) {
                    return -1;
                }
    
                assert false;
            }
    
            return var4.position();
        }

    这里的var1便是cbuf[],var2是0,var3是2,var4是根据cbuf[]创建的字符缓冲区,两者会同步改变,var5代表eof,var6是调用解码方法后返回的状态(CodeResult)。接着调用解码方法,该方法会把字节流bb里的数据解码成字符并填充到var4(即cbuf[])中,然后返回var6。对var6进行判断,如果是underflow,那代表解码器已经将字节流里的剩余数据全部解码到var4(cbuf[])中,这时候要判断是否还是输入(eof),如果还有输入,就要调用readBytes并返回状态,如果返回-1则表示已经eof,将eof置为true以便下次调用判断eof。如果var6状态时overflow,那说明var4(cbuf[])已满而字节流还有剩余,这时候跳出循环,进行一系列安全判断后返回var4.position()(即已读取的字符个数,因为position()返回的是下一个要被读或写的元素的索引,所以[0],[1]都被读写后,返回的就是2,即已读取2个字符,且两个字符就位于cbuf[]中)。

  • 相关阅读:
    27个提升效率的iOS开源库推荐
    HTTP Authorization
    两种方法删除NSUserDefaults所有记录
    label调整字间距,调整行间距
    iphone手机屏幕大小
    app 图标需要的大小
    多了一层或者多层响应者 如何实现跳转
    用python实现excel中查找指定字符的行信息
    Python 遍历一个目录,输出所有的文件名
    kettle HTTP client
  • 原文地址:https://www.cnblogs.com/MYoda/p/11195018.html
Copyright © 2011-2022 走看看