写程序时参数常变且难预知,用配置文件解决的方法
此心光明,亦复何言

在平时写程序时,有些参数时常会发生改变,且这种改变并非我们能够预先知晓。例如我们开发了一个操作数据库的模块,在开发过程中,当我们连接本地数据库时,其 IP、数据库名称、表名称、数据库主机等信息都属于本地的。要让这个操作数据的模块具备通用性,就不能将以上这些信息固定写在程序里。通常我们的做法是用配置文件来解决。
不同语言都拥有自身所支持的配置文件。在这些配置文件中,有许多变量是时常发生改变的。这样做的目的是为了给用户提供便利,使得用户能够在不依赖程序本身的情况下对相关的变量设置进行修改。例如,Python所支持的配置文件是.ini文件。与此同时,Python也具备自己用于读取配置文件的类ConfigParse,这样便于程序员或用户通过该类的方法来对.ini配置文件进行修改。Java 中的配置文件通常是.properties 文件,它的格式是文本文件。JDK 内置的 java.util.Properties 类能够支持.properties 文件的读写操作,从而为我们对.properties 文件的操作提供了便利。
一 .properties 文件的形式设数据如下:
#以下为服务器、数据库信息
dbPort = localhost
databaseName = mydb
dbUserName = root
dbPassword = root
#以下为数据库表信息
dbTable = mytable
#以下为服务器信息
ip = 192.168.0.9
我们假设上述信息保存在 db.properties 文件里。其中有以#开头的一行,这行是注释信息;在等号“= ”左边的部分被我们称作 key ;等号“= ”右边的部分被我们称作 value 。(这其实就是我们常说的键-值对)key 应当是我们程序中的变量。而 value 是根据实际情况进行配置的。
db.properties
Java 中有一个 Properties 类,它用于进行相关操作。这个 Properties 类在 Java 中有着特定的用途和功能。
Java 中存在一个较为重要的类叫 Properties(Java.util.Properties)。它主要被用于读取 Java 的配置文件。该配置文件的内容是以“键=值”的格式呈现的。并且,文本注释信息能够通过“#”来进行注释。
Properties类继承自Hashtable,如下:
Properties
Properties类提供了几个主要的方法:
加载(输入流 inStream)
这个方法能够从.properties 属性文件所对应的文件输入流里,把属性列表加载到 Properties 类对象中,也就是通过装载上面的 properties 文件,从而获取该文件里的所有键 - 值对,以便 getProperty(String key) 进行搜索。
如下面的代码:
创建了一个名为 pro 的 Properties 对象。
创建一个名为 in 的 FileInputStream 对象,该对象用于读取名为 "a.properties" 的文件。
pro.load(in);
in.close();
2 getProperty ( String key )
获取属性信息
在属性列表中用指定的键进行搜索,也就是通过参数 key 去获取 key 所对应的 value 。
设置属性(字符串类型的键,字符串类型的值)。
设置属性信息
即通过调用基类的put方法来设置 键 - 值对。
将一个 OutputStream 对象 out 和一个字符串 comments 作为参数传递给 store 方法。
这个方法会把 Properties 类对象所具有的属性列表保存到输出流里。
与 load 方法的作用相反,此方法会把键 - 值对写入到特定的文件当中去。
如下面的代码:
创建一个名为 oFile 的 FileOutputStream 对象,该对象用于将数据写入名为 file 的文件,并且指定要写入的文件名为 "a.properties"。
pro.store(oFile, "Comment");
oFile.close();
如果 comments 有内容,那么保存后的属性文件的第一行将会是#comments,这意味着注释信息;倘若 comments 没有内容,就不会有注释信息。
注释信息后面是属性文件的当前保存时间信息。
5 clear( )
清除所有装载的 键 - 值对。该方法在基类中提供。
load 和 getProperty最常用
我们有了以上几个方法,就能够对.properties 文件进行操作了。
2 Java读取Properties文件
Java读取 Properties 文件的方式有诸多,然而最为常用的乃是借助 java.lang.Class 类的 getResourceAsStream(String name)方法来达成,以下便是可以如此进行调用的方式:
获取当前类的资源流,资源名称为"资源 Name",将其赋值给输入流 in ,即 in = getClass().getResourceAsStream("资源 Name");
或者下面这种也常用:
创建了一个 FileInputStream 对象,参数为 filepath 。然后将这个 FileInputStream 对象作为参数传递给 BufferedInputStream 的构造函数,创建了一个 BufferedInputStream 对象。最后将这个 BufferedInputStream 对象赋值给 in 变量。
3 一个比较综合的实例
根据key读取value
读取properties的全部信息
写入新的properties信息
//关于Properties类常用的操作
public class TestProperties {
//根据Key读取Value
最后提取出与该键对应的具体值并返回。
创建了一个名为 pps 的 Properties 对象。
try {
创建了一个文件输入流对象,参数为 filePath 。然后使用该文件输入流对象创建了一个缓冲输入流对象。最后将创建好的缓冲输入流对象赋值给变量 in 。
pps.load(in);
获取到的字符串值为 pps 的属性 key 所对应的值。
System.out 会输出 key 加上等号以及 value
return value;
}catch (IOException e) {
e.printStackTrace();
return null;
}
}
//读取Properties的全部信息
公共静态地去获取所有的属性。获取的路径是一个字符串类型的 filePath。在这个过程中可能会抛出 IOException 异常。
Properties pps = new Properties();
创建一个输入流对象 in,该对象是一个缓冲输入流,它内部包含一个用于读取文件的文件输入流,而这个文件输入流的文件路径为 filePath。
pps.load(in);
获取配置文件的名字,通过枚举 en = pps.propertyNames(); 来实现。
while(en.hasMoreElements()) {
获取到的元素被强制转换为字符串类型并赋值给变量 strKey,这个元素是从 en 中取出的下一个元素。
获取到的字符串值为 strValue,这个值是通过 pps.getProperty(strKey)获取到的。
输出 strKey 与 strValue 拼接后的字符串,即 strKey + "=" + strValue 。
}
}
//写入Properties信息
公共静态 void 写入属性(字符串 filePath,字符串 pKey,字符串 pValue)抛出 IOException {
Properties pps = new Properties();
创建了一个输入流对象 in ,该对象是通过使用文件路径 filePath 来创建的文件输入流 new FileInputStream(filePath) 。
//从输入流中读取属性列表(键和元素对)
pps.load(in);
调用 Hashtable 的 put 方法。利用 getProperty 方法来提供并行性。
要求属性的键和值都使用字符串。返回值是调用 Hashtable 的 put 方法所得到的结果。
创建了一个用于写入数据的 OutputStream 对象,该对象是一个新的 FileOutputStream,其文件路径为 filePath 。
把 pKey 的属性值设为 pValue 。
以一种能够被 load 方法用于加载到 Properties 表的格式,
将此 Properties 表中的属性列表进行写入操作,写入的对象是输出流,写入的内容是属性列表中的键和元素对。
使用 out 调用 pps.store 并传入 "Update " 与 pKey 以及 " name" 进行更新操作。
}
公共静态的 void 方法 main,其参数为 String 类型的数组 args,并且会抛出 IOException 异常。
通过键“db.properties”获取到的值赋给了变量 value,而这个值对应的键是“name”,即 value 等于 GetValueByKey("db.properties", "name") 所返回的值。
//System.out.println(value);
获取所有的属性("db.properties")。
调用 WriteProperties 函数,传入参数 "db.properties"、"long" 和 "212"
}
}
结果:
db.properties中文件的数据为:
#Update long name
#Sun Feb 23 18:17:16 CST 2014
name=JJ
Weight=4444
long=212
Height=3333
三 小结
从上面的例子可以清晰看出,Java 中操作配置文件是较为简单的。在一个包含大量配置信息的模块或系统中,我们有进行封装一个专门类以供使用的必要。通过最后的 main 函数来进行调用。
世界上所有的追求都是因为热爱
一枚爱编码 爱生活 爱分享的IT信徒
— hongXkeX