Properties——属性集合

Properties

  • 前言
  • key和value的定义
  • load加载输入流
  • 示例

前言

对于很多java开发者,第一次接触这个Properties类的时候可能是在接触Spring框架时,以为这是框架提供的功能,其实他是地地道道的JDK原生工具类。代表一个持久的属性集合,属性可以被保存到一个流或者从流中加载。属性列表中每一个键和对应的值都是字符串。

key和value的定义

Properties类以一个简单的面向行的格式从输入流中读取一个属性列表(key,value对)。遇到换行符才才认为行结束,它读取的逻辑行,逻辑行可以通过使用反斜杠字符\转义行终止序列,从而使逻辑行跨越多个自然行,简单说可以通过\来把多个自然行续成一个逻辑行。

int readLine() throws IOException {
            int len = 0;
            char c = 0;

            boolean skipWhiteSpace = true;
            boolean isCommentLine = false;
            boolean isNewLine = true;
            boolean appendedLineBegin = false;
            boolean precedingBackslash = false;
            boolean skipLF = false;
			//开始读取一个逻辑行
            while (true) {
                if (inOff >= inLimit) {
                //1. 读取整个文件内容总长度
                    inLimit = (inStream==null)?reader.read(inCharBuf)
                                              :inStream.read(inByteBuf);
                    inOff = 0;
                    if (inLimit <= 0) {//没有内容直接返回
                        if (len == 0 || isCommentLine) {
                            return -1;
                        }
                        if (precedingBackslash) {
                            len--;
                        }
                        return len;
                    }
                }
                if (inStream != null) {//有内容
                    //The line below is equivalent to calling a
                    //ISO8859-1 decoder.
                    //读取字符
                    c = (char) (0xff & inByteBuf[inOff++]);
                } else {
                    c = inCharBuf[inOff++];
                }
                if (skipLF) {
                    skipLF = false;
                    if (c == '\n') {
                        continue;
                    }
                }
                if (skipWhiteSpace) {
                    if (c == ' ' || c == '\t' || c == '\f') {
                        continue;
                    }
                    if (!appendedLineBegin && (c == '\r' || c == '\n')) {
                        continue;
                    }
                    skipWhiteSpace = false;
                    appendedLineBegin = false;
                }
                if (isNewLine) {
                    isNewLine = false;
                    //对注释的处理
                    if (c == '#' || c == '!') {
                        isCommentLine = true;
                        continue;
                    }
                }
				//正常的字符流
                if (c != '\n' && c != '\r') {
                    lineBuf[len++] = c;
                    if (len == lineBuf.length) {
                        int newLength = lineBuf.length * 2;
                        if (newLength < 0) {
                            newLength = Integer.MAX_VALUE;
                        }
                        char[] buf = new char[newLength];
                        System.arraycopy(lineBuf, 0, buf, 0, lineBuf.length);
                        lineBuf = buf;
                    }
                    //flip the preceding backslash flag
                    if (c == '\\') {
                        precedingBackslash = !precedingBackslash;
                    } else {
                        precedingBackslash = false;
                    }
                }
                else {//达到行尾(换行符)
                    // reached EOL
                    if (isCommentLine || len == 0) {
                        isCommentLine = false;
                        isNewLine = true;
                        skipWhiteSpace = true;
                        len = 0;
                        continue;
                    }
                    if (inOff >= inLimit) {
                        inLimit = (inStream==null)
                                  ?reader.read(inCharBuf)
                                  :inStream.read(inByteBuf);
                        inOff = 0;
                        if (inLimit <= 0) {
                            if (precedingBackslash) {
                                len--;
                            }
                            return len;
                        }
                    }
                    if (precedingBackslash) {
                        len -= 1;
                        //skip the leading whitespace characters in following line
                        skipWhiteSpace = true;
                        appendedLineBegin = true;
                        precedingBackslash = false;
                        if (c == '\r') {
                            skipLF = true;
                        }
                    } else {
                        return len;
                    }
                }
            }
        }

load加载输入流

加载输入流,并转换成Properties,每读取一行,找到首次出现的= :空格,之前的作为key值,之后的作为value

private void load0 (LineReader lr) throws IOException {
        char[] convtBuf = new char[1024];
        int limit;
        int keyLen;
        int valueStart;
        char c;
        boolean hasSep;
        boolean precedingBackslash;
	/**lr.readLine()每次读取一个逻辑行,遇到换行会结束
	返回,这个逻辑行有效长度,直到读取不到数据结束
	*/
        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.
                //首次遇到等号、:、或者空格找到了key,value从下一个字符开始
                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++;
            }
            String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
            String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
            put(key, value);
        }
    }

示例

Properties pt = new Properties();
        pt.load(new FileInputStream("src/main/resources/myp.txt"));
        Set keyset = pt.keySet();
        for(Object key:keyset){
            System.out.println(key + "=" + pt.getProperty(key.toString()));
        }

你可能感兴趣的:(java,开发语言)