`
weiqiang.yang
  • 浏览: 155214 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Java Properties类加载配置文件转义问题

阅读更多
场景:
    配置文件config.properties
    配置项cfg.regexp=\d+\t
    加载配置文件代码
    InputStream ins = PropManager.class.getResourceAsStream("/config.properties");
    prop.load(ins);

现象:
    打印cfg.regexp的值输出为"d+    ",而不是期望的"\d+\t"

原因:
    看了下代码,发现Properties类对'\'做了转义处理,而且只处理'\uxxxx', '\t','\n','\r','\f'这几种情况,对于其他情况,就简单的把'\'吞掉了
while (off < end) {
            aChar = in[off++];
            if (aChar == '\\') {
                aChar = in[off++];   
                if(aChar == 'u') {
                    // Read the xxxx
                    int value=0;
		    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 {
                    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++] = (char)aChar;
            }
        }

解决方法:
我的解决方法是,自己写个简单的解析
约定
  • 每行第一次出现的'='作为分割符(Properties类可以支持key:value格式)
  • key和value都忽略前后空白字符
  • 不对字符串做转义处理


            while((line = buffReader.readLine())!=null){
            	line = line.trim();
            	if(line.startsWith("#") || line.equals("")){// 忽略#开头的注释
            		continue;
            	}
            	
            	int index = line.indexOf('=');
            	if(index <= 0){
            		logger.error("********错误的配置文件格式!********line = " + line);
            		continue;
            	}
            	String key = line.substring(0, index).trim();
            	String value = (index+1>=line.length()) ? "":line.substring(index+1).trim();// 避免越界
            	prop.put(key, value);
            }


之所以把它记下来是因为我跟同事说起这个现象的时候,同事发现他之前写的代码用过类似的正则表达式配置方式,正则表达式里面希望匹配绝对的'\.',而经过Properties类转义之后变成了'.',意义就变成了“任意字符”,由于运行并不报错,而且某系情况下结果还是正确的,于是一个潜在的bug就出现了
1
1
分享到:
评论
1 楼 beneo 2010-12-23  
赞。。。我就碰到了这个潜在的问题,看来覆盖测试还是非常必要的

相关推荐

Global site tag (gtag.js) - Google Analytics