Properties类理解

前言

Properties类通过接受文件流输入,解析成对应的Map键值队,属于JDK自带基础类。今天重点通过源码解析其具体逻辑实现

load函数

从源码观察,接受Reader类。
//将输出流转成LineReader,LineReader是Properties的内部类,功能是可以一行一行的读数据。

public synchronized void load(InputStream inStream) throws IOException {
    load0(new LineReader(inStream));
}

load0函数

private void load0 (LineReader lr) throws IOException {
    char[] convtBuf = new char[1024];
    int limit;
    int keyLen;
    int valueStart;
    char c;
    boolean hasSep;
    boolean precedingBackslash;

    while ((limit = lr.readLine()) >= 0) {
        c = 0;
        keyLen = 0;
        valueStart = limit;
        hasSep = false;

        //System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
        precedingBackslash = false;
        while (keyLen < limit) {
            c = lr.lineBuf[keyLen];
            //need check if escaped.
            if ((c == '=' ||  c == ':') && !precedingBackslash) {
                valueStart = keyLen + 1;
                hasSep = true;
                break;
            } else if ((c == ' ' || c == '\t' ||  c == '\f') && !precedingBackslash) {
                valueStart = keyLen + 1;
                break;
            }
            if (c == '\\') {
                precedingBackslash = !precedingBackslash;
            } else {
                precedingBackslash = false;
            }
            keyLen++;
        }
        while (valueStart < limit) {
            c = lr.lineBuf[valueStart];
            if (c != ' ' && c != '\t' &&  c != '\f') {
                if (!hasSep && (c == '=' ||  c == ':')) {
                    hasSep = true;
                } else {
                    break;
                }
            }
            valueStart++;
        }
        //取key和value
        String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
        String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
        put(key, value);
    }
}

loadConvert函数

private String loadConvert (char[] in, int off, int len, char[] convtBuf) {
    if (convtBuf.length < len) {
        int newLen = len * 2;
        if (newLen < 0) {
            newLen = Integer.MAX_VALUE;
        }
        convtBuf = new char[newLen];
    }
    char aChar;
    char[] out = convtBuf;
    int outLen = 0;
    int end = off + len;

    while (off < end) {
        aChar = in[off++];
        //判断是否为转义字符
        if (aChar == '\\') {
            aChar = in[off++];
            //判断是否是unicode
            if(aChar == 'u') {
                // Read the xxxx
                int value=0;
                //如果是unicode的话,顺序读取4位并转换成字符串
                for (int i=0; i<4; i++) {
                    aChar = in[off++];
                    switch (aChar) {
                      case '0': case '1': case '2': case '3': case '4':
                      case '5': case '6': case '7': case '8': case '9':
                         value = (value << 4) + aChar - '0';
                         break;
                      case 'a': case 'b': case 'c':
                      case 'd': case 'e': case 'f':
                         value = (value << 4) + 10 + aChar - 'a';
                         break;
                      case 'A': case 'B': case 'C':
                      case 'D': case 'E': case 'F':
                         value = (value << 4) + 10 + aChar - 'A';
                         break;
                      default:
                          throw new IllegalArgumentException(
                                       "Malformed \\uxxxx encoding.");
                    }
                 }
                out[outLen++] = (char)value;
            } else {
                //如不是unicode,则只支持以下几中转义字符
                if (aChar == 't') aChar = '\t';
                else if (aChar == 'r') aChar = '\r';
                else if (aChar == 'n') aChar = '\n';
                else if (aChar == 'f') aChar = '\f';
                out[outLen++] = aChar;
            }
        } else {
            out[outLen++] = aChar;
        }
    }
    return new String (out, 0, outLen);
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文转自Java 最常见 200+ 面试题全解析:面试必备(转载) 序言 在本篇文章开始之前,我想先来回答一个问题...
    林伟成阅读 1,206评论 0 3
  • Java 语言支持的类型分为两类:基本类型和引用类型。整型(byte 1, short 2, int 4, lon...
    xiaogmail阅读 1,369评论 0 10
  • Java基础类库 本章思维导图 用户互动 使用Scanner获取键盘输入 Scanner主要提供了两个方法来扫描输...
    帅到没朋友fx阅读 582评论 0 1
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,575评论 16 22
  • 创业是很多人的梦想,多少人为了理想和不甘选择了创业来实现自我价值,我就是其中一个。 创业后,我由女人变成了超人,什...
    亦宝宝阅读 1,878评论 4 1