类 Properties 的用法

 今天工作中多处用到了这个类,特此研究下他的具体用法,主要是加载配置文件,然后以key和value形式加载出来。

测试程序如下:

public static void main(String[] args)throws IOException {
        try {
            @SuppressWarnings("unused")
            InputStream stream = Class.forName("com.lvmama.properties.PropertiesTest").getResourceAsStream("webService.properties");
            Properties p=new Properties();
            p.load(stream);
            System.out.println(p.getProperty("TAIPING_SERVER"));
            p.setProperty("2", "sdfsdf");
            System.out.println(p.getProperty("2"));
        } catch (ClassNotFoundException e){
            // TODO Auto-generated catchblock
            e.printStackTrace();
        }
         
    }

公司封装了一个工具类用来加载配置文件,类如下:


package com.lvmama.vst.insurant.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 配置管理对象
 * @author clj 2009-9-12
 *
 */
public class Configuration {

	private static final Log log = LogFactory.getLog(Configuration.class);
	private static Configuration configuration = null;

	private Configuration() {

	}

	/**
	 * 得到配置对象
	 * 
	 * @return
	 */
	public static Configuration getConfiguration() {
		if (configuration == null) {
			configuration=new Configuration();
		}
		return configuration;
	}

	/**
	 * 获取配置的资源文件
	 * 
	 * @param resource
	 * @return
	 */
	public Properties getConfig(String resource) {
		Properties config = new Properties();
		try {
			config.load(getResourceAsStream(resource));
		} catch (IOException e) {
			log.error("装载配置文件异常", e);
		}
		return config;
	}

	/**
	 * 获取配置的资源文件数据流
	 * 
	 * @param resource
	 * @return
	 */
	public InputStream getResourceAsStream(String resource) {
		String realSource = resource.startsWith("/") ? resource.substring(1) : resource;
		return Thread.currentThread().getContextClassLoader().getResourceAsStream(realSource);
	}
}

下面我们开始分析它的源码

先看load源码,进入Properties

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


执行实例化内部类LineReader

        public LineReader(InputStreaminStream) {
            this.inStream = inStream;
            inByteBuf = new byte[8192];
    }
 

然后执行该类的加载配置信息主方法;方法如下:

  

private void load0 (LineReaderlr) throws IOException {
        char[] convtBuf = newchar[1024];
        int limit;
        int keyLen;
        int valueStart;
        char c;
        boolean hasSep;
        boolean precedingBackslash;
// readLine()方法开始调用LineReader的方法,主要加载配置文件中的数据信息
        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++;
            }
            String key = loadConvert(lr.lineBuf,0, keyLen, convtBuf);
            String value = loadConvert(lr.lineBuf,valueStart, limit - valueStart, convtBuf);
        put(key,value);
    }
}

接下来看下这个LineReader类的readLine()方法

   int  inLimit= (inStream==null)?reader.read(inCharBuf)

                                     :inStream.read(inByteBuf);

先读取一个数据放入inByteBuf

  c = (char) (0xff & inByteBuf[inOff++]);//对得到的值进行转码


   //跳过空格键
        if (skipWhiteSpace){
           if (c == ' ' || c == '\t' || c == '\f') { //判断是否空格,制表符换页符
            continue;  //如果是结束本次循环
           }
           if (!appendedLineBegin && (c == '\r' || c == '\n')) { //跳过换行符和回车符
            continue;
           }
           skipWhiteSpace = false;
           appendedLineBegin = false;
        }

//以下判断是否新行,新行的话则给isCommentLine做个标准,跳出该循环

        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 = newchar[newLength];
            System.arraycopy(lineBuf, 0,buf, 0, lineBuf.length);// lineBuf复制到buf
            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) {
               return len;
            }
           }
           if (precedingBackslash) {
            len -= 1;
            //skip the leading whitespacecharacters in following line
            skipWhiteSpace = true;
            appendedLineBegin = true;
            precedingBackslash = false;
            if (c == '\r') {
                            skipLF = true;
            }
           } else {
            return len;
           }
        }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值