转自:http://blog.csdn.net/ly5156/article/details/6912587
前段时间有朋友问我有关Java读取外置配置信息的方法,其实以前我也没太在意,都是用到的时候东拼西凑,正好趁这个机会,我也把好好总结了一下。
在Java中读取配置无外乎这样几种常见方法:
1.读取ini配置文件:
这种方法现在基本上已经很少采用了。我在上个项目中曾经考虑过,上网找了N多代码,都不是太好使,经常遇到莫名其妙的问题。并且ini文件本身就有很多限制,比如文件大小等等。读写的时候基本上也要靠自己手动编写底层文件读写操作代码来读写ini文件,然后得到内容的串,然后通过串的操作来实现读写配置信息,过程相当繁琐。用起来就俩字儿- -费劲。
2.读取xml配置信息:
感觉这种方法应该是最好的了。随着网络的普及,xml这种格式已经越来越流行,它不仅可以用来存储配置信息,而且由于定义良好的格式,也可以用来在各个App中传递参数。且用其存储配置信息,拥有非常好的层次。目前在Java Web中应用及其广泛,几乎所有的Java Web框架都是用xml来存储配置信息,包括Tomcat。
Java中读取xml配置信息主要是通过DOM(文档对象模型)来实现的。简而言之就是将一个xml文件读取到内存中,并且将其映射为一个Java对象,这样Java操作xml就可以通过操作对象来实现。但是Java自带的xml读写类库(DOM)用着特费劲,比较繁琐,所以衍生出了一些个开源的dom框架,最著名的有dom4j和jdom。其中以dom4j应用最为广泛,拥有更高的效率。
dom4j读写xml的基本过程为:首先要获得一个SAXReader类型的字符输入流对象,该对象通过read(File xmlFile)方法来读取硬盘上的的xml文件,读取后获得一个Document类型的对象,至此DOM中的文档->对象之间的映射已经完成。以后操作xml文件,其实都是对这个Document对象的操作,你可以通过getRootElememt()方法获得xml的根节点(Elemtnt类型的对象),再通过Element对象的elememtIterator()方法获得迭代器来遍历该元素下的子元素,反复递归调用可实现对整个xml树的遍历。如下的例子:
例程1.
SAXReader reader = new SAXReader();
//get the DOM Mapping
Document document = reader.read(new File("user.xml"));
//get the root element.
Element elem = document.getRootElement();
System.out.println("RootElementName:" + elem.getName());
//traverse the elemtnt's child-elements
for(Iterator<Element> i = elem.elementIterator(); i.hasNext(); )
{
Element element = i.next();
System.out.println(element.getName());
}
当然,如果你希望直接通过元素路径来找到相应结点的属性值,可以通过XPath实现。
例程2.
//XPath access the XML file,return all the nodes those match the XPath.
List<Node> list = (List<Node>)document.selectNodes("//root/child1/bbb");
for(Node node : list)
{
System.out.println(node.getName() + "-" + node.valueOf("@name") + "-" + node.getStringValue());
}
写入配置信息的时候,需要一个XMLWriter类的对象。构造这个对象的时候需要向其传递这样几个参数:一个用来执行输出的字符输出流(FileWriter)、表示输出格式的OutputFormat对象(可以没有),该对象可以使输出的格式更加美观。然后通过XMLWriter对象的write(Document xmlDocument)方法将你的Document对象通过Writer输出到文件中。当然,你也可以采用其他字符输出流如ObjectWriter,这样就可以将Document对象序列化。
例程3.
Document document = DocumentHelper.createDocument();
Element root = document.addElement("hibernate-mapping");
Element classElement = root.addElement("class")
.addAttribute("name", "none")
.addAttribute("table", "aiur");
classElement.addElement("property").addAttribute("name", "username");
//Write the XMLDocument
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileWriter( "User1.hbm.xml" ), format);
writer.write(document);
writer.close();
return document;
dom4j使用时需要引入相应的jar包。本文示例所采用的是dom4j-2.0.0-ALPHA-2版本,然后引入dom4j-2.0.0-ALPHA-2.jar和jaxen-1.1-beta-6.jar更多的用法可以参阅dom4j的API。
3.读取Properties文件:
Properties其实是Java系统类库中的一个类,专门用来读写后缀名为.properties的文件,这也是Java中默认的配置文件。它的读写比xml方式要简单,可以应付一些比较小型的,配置信息结构不复杂且零散系统。Properties文件其实就是文本文件,配置信息在该文件中以Key=Value的形式存放。由此可以看出,它和ini文件是差不多的,只不过由于有了Java类库的支持,读写操作更加简洁而已。
读写properties文件的大致流程为:首先需要获得一个Properties类的对象和一个指向要读取的文件的字节数入流FileInputStream类型的对象,然后调用Properties对象的load(InputStream fis)方法载入.properties的配置文件。这样就可以通过properties对象的getProperty(String key)方法来获得key所对应的属性值。写入的时候需要一个指向要输出的文件的字节输出流FileOutputStream的对象,然后调用setProperty(String key, String value)设置属性,然后调用properties对象的store()方法,并将FileOutputStream对象作为参数传递给该方法即可实现文件的保存。
例程4.
这段代码是我曾经在项目中用到的,所以引入了一些个项目中的类,导致这段代码不能单独直接运行,在这里只是为了展示Properties文件的读写方法。
package com.none.Common;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Properties;
import com.none.BLL.ExceptionLog;
/**
* 配置文件读写类
* @author Aiur
*
*/
public class ConfigFile
{
private static File configFile = new File(Constants.path + "/Config.properties");
private static ConfigFile config= null;
/**
* 构造器采用Singleton模式,初始化相关信息
*/
private ConfigFile()
{
if(!configFile.exists())
{
FileOutputStream fos;
try
{
fos = new FileOutputStream(new File(Constants.path + "/Config.properties"));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
String defaultConfigInfo = "ServerName=localhost\n"
+ "Port=1433\n"
+ "DatabaseName=LibraryManagement\n"
+ "UserName=\n"
+ "Password=\n"
+ "UseTimes=-1\n";
bw.write(defaultConfigInfo);
bw.close();
} catch (FileNotFoundException e)
{
ExceptionLog.writeLog(Constants.getCurrentDate() + e.getMessage() + "\n");
} catch (IOException e)
{
ExceptionLog.writeLog(Constants.getCurrentDate() + e.getMessage() + "\n");
}
}
config = this;
}
/**
* 获取配置文件信息
* @param key 属性名
* @return 属性值
*/
public static String getProperty(String key)
{
if(config == null)
{
new ConfigFile();
}
try
{
// 定义一个properties对象
Properties properties = new Properties();
// 读取properties
FileInputStream fis = new FileInputStream(configFile);
// 加载properties文件
properties.load(fis);
// 读取properties中的某一项
String value = properties.getProperty(key);
return value;
} catch (IOException e)
{
ExceptionLog.writeLog(Constants.getCurrentDate() + e.getMessage() + "\n");
return null;
}
}
/**
* 修改配置文件信息
* @param key 属性名
* @param value 属性值
* @return 状态值,1表示操作成功
*/
public static int setProperty(String key, String value)
{
if(config == null)
{
new ConfigFile();
}
try
{
// 定义一个properties对象
Properties properties = new Properties();
// 读取properties
FileInputStream fis = new FileInputStream(configFile);
// 加载properties文件
properties.load(fis);
// 设置properties中的某一项
properties.setProperty(key, value);
FileOutputStream fout = new FileOutputStream(configFile);
properties.store(fout, "");//保存文件
fout.close();
return 1;
} catch (IOException e)
{
ExceptionLog.writeLog(Constants.getCurrentDate() + e.getMessage() + "\n");
return 0;
}
}
}