对properties文件读取里面的属性
1、首先通过当前线程的上下文类加载去将properties文件的路径资源转化为InputStream
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dqms.properties");
2、然后通过Properties类去加载这个inputStream就读取了properties文件
private static Properties dataProps=new Properties();
dataProps.load(inputStream);
3、想要获取里面的属性,只需要调用Properties类的getProperty(name)就可获取name的值,String类型。
dataProps.getProperty(name)
上面基本就能获取值,有需要更加了解的看下面源码:
1、对getResourceAsStream(String xx)进行分析,将属性文件读入内存的InputStream流中。
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
try {
return url != null ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
/*获取资源的路径,首先从自身的类加载获取资源,如果没有知道就去根目录去找,如果还是空则为null*/
private final ClassLoader parent;
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name); //本项目资源路径下去找
} else {
url = getBootstrapResource(name);//JDK\jre\lib路径下去找
}
if (url == null) {
url = findResource(name); //null
}
return url;
}
//英文解释说该方法最好被重写
protected URL findResource(String name) {
return null;
}
/*url打开这个链接并返回InputStream*/
public final InputStream openStream() throws java.io.IOException {
return openConnection().getInputStream();
}
2、Properties类对Input进行load加载转化为properties对象。
通过源码可以看到对properties的格式要求有五种:(1)冒号:(2)等号=(3)空格“ ”(4)制表符\t(5)换页符\f
//synchronized进行同步,从InputStream里面读取properties集合(键值对),读取完成后,该InputStream还是开着的,没有关闭
public synchronized void load(InputStream inStream) throws IOException {
load0(new LineReader(inStream));
}
//看看源码发现他把每行的键值对,存到HashTable的map上
private void load0 (LineReader lr) throws IOException {
char[] convtBuf = new char[1024];
int limit; //每一行的最后字符位置
int keyLen; //每一行的key的长度
int valueStart;//每一行的value的开头字符位置
char c;
boolean hasSep;
boolean precedingBackslash;
//lr.readLine()会每行每行读取,》=0说明最后还有值
while ((limit = lr.readLine()) >= 0) {
c = 0;
keyLen = 0; //每一行keyLen都会从每行的头开始,像指针,到一定位置
valueStart = limit;
hasSep = false;
//System.out.println("line=<" + new String(lineBuf, 0, limit) + ">");
precedingBackslash = false;
//循环key部分
while (keyLen < limit) {
c = lr.lineBuf[keyLen]; //在每一行的位置上的字符,从0开始
//检查=或:这两种格式
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++;
}
//循环value部分
while (valueStart < limit) {
c = lr.lineBuf[valueStart];//在每一行的位置上的字符,从valueStart开始
if (c != ' ' && c != '\t' && c != '\f') {
if (!hasSep && (c == '=' || c == ':')) {
hasSep = true;
} else {
break;
}
}
valueStart++;//遇到空格,制表符,换页符隔过去,value开头的位置直接++;
}
String key = loadConvert(lr.lineBuf, 0, keyLen, convtBuf);
String value = loadConvert(lr.lineBuf, valueStart, limit - valueStart, convtBuf);
put(key, value); //因为Properties继承了HashTable,所以这个put方法是HashTable的方法
}
}
3、getProperties("xx")实质是:map的get();
//因为继承了HashTable,调用super.get(),是调用map.get()
public String getProperty(String key) {
Object oval = super.get(key);
String sval = (oval instanceof String) ? (String)oval : null;
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}