java config file escape problem

Scenario: 
    Configuration file config.properties 
    configuration item cfg.regexp=\d+\t 
    Load configuration file code 
    InputStream ins = PropManager.class.getResourceAsStream("/config.properties"); 
    prop.load(ins); 

Phenomenon: 
    print cfg. The value of regexp is output as "d+ ", not the expected "\d+\t" 

Reason: 
    After reading the code, I found that the Properties class has escaped '\', and only handles '\uxxxx', '\t ','\n','\r','\f' In other cases, simply swallow the '\' 

 1 while (off < end) {  
 2             aChar = in[off++];  
 3             if (aChar == '\\') {  
 4                 aChar = in[off++];     
 5                 if(aChar == 'u') {  
 6                     // Read the xxxx  
 7                     int value=0;  
 8             for (int i=0; i<4; i++) {  
 9                 aChar = in[off++];    
10                 switch (aChar) {  
11                   case '0': case '1': case '2': case '3': case '4':  
12                   case '5': case '6': case '7': case '8': case '9':  
13                      value = (value << 4) + aChar - '0';  
14                  break;  
15               case 'a': case 'b': case 'c':  
16                           case 'd': case 'e': case 'f':  
17                  value = (value << 4) + 10 + aChar - 'a';  
18                  break;  
19               case 'A': case 'B': case 'C':  
20                           case 'D': case 'E': case 'F':  
21                  value = (value << 4) + 10 + aChar - 'A';  
22                  break;  
23               default:  
24                               throw new IllegalArgumentException(  
25                                            "Malformed \\uxxxx encoding.");  
26                         }  
27                      }  
 28                      out[outLen++] = ( char )value;  
29                  } else {  
 30                      if (aChar == 't') aChar = '\t' ;   
31                      else  if (aChar == 'r') aChar = '\r' ;  
32                      else  if (aChar == 'n') aChar = '\n' ;  
33                      else  if (aChar == 'f') aChar = '\f' ;   
34                      out[outLen++] = aChar;  
              out[outLen++] = (char)aChar;  
38             }  
39         }  

Solution: 
My solution is to write a simple parsing 
convention  myself

    • The first occurrence of '=' in each line is used as a separator (Properties class can support key:value format)
    • Both key and value ignore leading and trailing whitespace characters
    • Do not escape strings
 1 while((line = buffReader.readLine())!=null){  
 2     line = line.trim();  
 3     if(line.startsWith("#") || line.equals("")){// 忽略#开头的注释  
 4         continue;  
 5     }  
 6       
 7     int index = line.indexOf('=');  
 8     if(index <= 0){  
 9         logger.error("********错误的配置文件格式!********line = " + line);  
10         continue;  
11     }  
12     String key = line.substring(0, index).trim();  
13     String value = (index+1>=line.length()) ? "":line.substring(index+1).trim();// 避免越界  
14     prop.put(key, value);  
15 }  

之所以把它记下来是因为我跟同事说起这个现象的时候,同事发现他之前写的代码用过类似的正则表达式配置方式,正则表达式里面希望匹配绝对的'\.',而经过Properties类转义之后变成了'.',意义就变成了“任意字符”,由于运行并不报错,而且某系情况下结果还是正确的,于是一个潜在的bug就出现了 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325227433&siteId=291194637