摘 要:本文就如何在Java下对配置文件进行操作,给出了具体的解决方法,用户可以直接使用这些代码加入到应用程序中,从而方便地实现对配置文件进行控制。
关键字:解析 配置文件
我们在编写程序时,经常要使用配置文件,对系统环境进行配置,或触发进程、控制应用程序等。下面,我们就谈谈如何使用Java来实现对配置文件的操作:
一、类似INI文件的控制方法
下面是某配置文件的内容片断:
[UserInfo]
UserName = Ad;
PassWord = xyz;
… … …
[SysInfo]
conFileName = MyCon.ini;
FileSize = 64;
我们给出此种INI文件的操作方法,其中[UserInfo]等为节名,用中括号括起来,下面的如UserName= Ad;为节点名及结点名,分号为结束标志。
/**************************************************************************
*<p>功能:取得配置文件中指定结点的配置信息</p>
*<p>方法:遍历结点,找出符合条件的节名;同样,遍历节点,取出结点名</p>
*@parameters:String asSource 查找的源字符串
*@parameters:String asSectionName 节名
*@parameters:String asNodeName 结点名
*@returns: String 指定结点的配置信息字符串
***************************************************************************/
private String getNode(String asSource,String asSectionName,String asNodeName){
int liNodeCount; // 统计指定字符串中指定字符的数量
int liBegin = 0; //关键字开始位置
int liEnd; //关键字结束位置
String lsSubs;
String lsRet = "";
// getCharsCount()统计指定字符串中指定字符的数量
liNodeCount =getCharsCount(isContent,"[");
for (int i = 0;i < liNodeCount;i++){
liBegin = asSource.indexOf ("[",liBegin);
liEnd = asSource.indexOf ("]",liBegin);
lsSubs = asSource.substring(liBegin + 1,liEnd);
liBegin = liEnd;
lsSubs = lsSubs.trim().toLowerCase();
if(lsSubs.equals(asSectionName.toLowerCase())){
liBegin = asSource.indexOf (asNodeName,liBegin);
liBegin = asSource.indexOf ("=",liBegin);
liEnd = asSource.indexOf (";",liBegin);
lsRet = asSource.substring (liBegin + 1,liEnd).trim();
break;
}
}
return lsRet;
}
/**************************************************************************
*<p>功能: 设置配置文件中指定节点的配置信息</p>
*@parameters:String asSource 查找的源字符串
*@parameters:String asSectionName 节名
*@parameters:String asNodeName 结点名
*@parameters:String asNodeValue 结点值
*@returns: String 完成设置的字符串
***************************************************************************/
private synchronized String setNode(String asSource,String asSectionName,
String asNodeName,String asNodeValue){
int liNodeCount;
int liBegin = 0;
int liEnd;
String lsSubs,lsLeft,lsRight;
String lsContent = asSource;
if (asSource == null) asSource = "";
if (asNodeValue == null) return asSource;
asNodeValue = " " + asNodeValue;
liNodeCount = Function.getCharsNumber(isContent,"[");
for (int i = 0;i < liNodeCount;i++){
liBegin = asSource.indexOf ("[",liBegin);
liEnd = asSource.indexOf ("]",liBegin);
lsSubs = asSource.substring(liBegin + 1,liEnd);
liBegin = liEnd;
lsSubs = lsSubs.trim().toLowerCase();
if(lsSubs.equals(asSectionName.toLowerCase())){
liBegin = asSource.indexOf (asNodeName,liBegin);
liBegin = asSource.indexOf ("=",liBegin);
liEnd = asSource.indexOf (";",liBegin);
lsLeft = asSource.substring (0,liBegin + 1);
lsRight = asSource.substring (liEnd);
lsContent = lsLeft + asNodeValue + lsRight;
break;
}
}
Function.writeStringToFile(lsContent,isConfigFileName);//写入结点值
return lsContent;
}
/**************************************************************************
*<p>功能: 程序运行环境变量配置文件的读取,放到各成员变量中</p>
*@parameters:String asConfigFileName 配置文件名
*@returns: boolean 成功 true 失败 false
***************************************************************************/
public boolean readCfgFile(String asConfigFileName){
String lsNodeValue;
File loFile;
try {
isConfigFileName = asConfigFileName;
loFile = new File(asConfigFileName);
if (loFile.exists() == false) return false;
// readFileToString()读取文本文件内容,并放入字符串变量中
isContent = readFileToString(isConfigFileName);
if (isContent == null || isContent.equals("")) return false;
//UserInfo节点的UserName结点值
lsNodeValue = getNode(isContent," UserInfo","UserName");
if (lsNodeValue.equals("")) throw new Exception("Parameter < UserInfo/UserName > not found!");
… … …(其余部分节略)
}
二、XML配置文件的读取处理
XML是Extensible Markup Language的简写,一种扩展性标识语言。XML文档是自描述的,不仅人能读懂XML文档,计算机也能处理。XML表示数据的方式真正做到了独立于应用系统,并且数据能够重用。XML文档被看作是文档的数据库化和数据的文档化。因此我们经常用XML文档进行数据交换。有时候为了使用上的方便,也可以将XML文档作为Java程序的配置文件。实际上,对XML文件的操作主要是对XML文件的解析。现在有好几种XML的解析器,这里我们用apache 的解析器(可以到http://www.apache.org/站点查找相关的内容)。
下面,我就Java下如何操作XML格式的配置文件,给出具体的代码。下面是配置文件的内容片断:
<UserInfo UserName = ' Ad '>
< PassWord > xyz </ PassWord >
</ UserInfo >
… … …
< SysInfo>
< conFileName > MyCon</ conFileName >
< FileSize >64</ FileSize >
</ SysInfo>
实现代码:
import java.io.*;
import java.util.*;
import org.apache.xerces.parsers.*;
import org.w3c.dom.*;
import org.apache.xml.serialize.*;
private DOMParser ioDOMParser; //XML解析器
private Document ioDoc; //DOM文档树
/**************************************************************************
*<p>功能: 解析指定XML文件到DOM树</p>
*@parameters: String asXMLFileName XML文件名
*@returns: boolean 成功 true 失败 false
***************************************************************************/
public boolean parseXMLFile(String asXMLFileName) {
try {
ioDOMParser = new DOMParser();
ioDOMParser.parse(asXMLFileName);
ioDoc = ioDOMParser.getDocument();
ioDoc.normalize();
}
catch(Exception ex) {
System.out.println(getClass() + ".parseXMLFile error: " + ex.getMessage());
return false;
}
return true;
}
/**************************************************************************
*<p>功能: 解析指定节点的内容,返回第一个符合条件的值</p>
*@parameters: String asNodeName 指定节点的名称
*@returns: String 解析结果(失败为null)
***************************************************************************/
public String getNodeValue(String asNodeName) {
NodeList loNodeList;
Node loNode;
Element loElement;
String lsNodeValue;
try {
if (asNodeName == null || asNodeName.equals("")) return null;
loNodeList = ioDoc.getElementsByTagName(asNodeName);
if (loNodeList.getLength() <= 0) return null;
loElement = (Element)loNodeList.item(0);
loNode = loElement.getFirstChild();
if (loNode == null) return null;
lsNodeValue = loNode.getNodeValue().trim();
}
catch(Exception ex) {
System.out.println(getClass() + ".getNodeValue error: " + ex.getMessage());
return null;
}
return lsNodeValue;
}
/**************************************************************************
*<p>功能: 解析指定节点的属性的内容,返回第一个符合条件的值</p>
*@parameters: String asNodeName 指定节点的父子层次名称
*@parameters: String asAttrName 指定属性名称
*@returns: String 解析结果(失败为null)
***************************************************************************/
public String getAttrValue(String asNodeName,String asAttrName) {
NodeList loNodeList;
Node loNode;
Element loElement;
String lsAttrValue;
try {
if (asNodeName == null || asNodeName.equals("")) return null;
if (asAttrName == null || asAttrName.equals("")) return null;
loNodeList = ioDoc.getElementsByTagName(asNodeName);
if (loNodeList.getLength() <= 0) return null;
loElement = (Element)loNodeList.item(0);
lsAttrValue = loElement.getAttribute(asAttrName).trim();
}
catch(Exception ex) {
System.out.println(getClass() + ".getAttrValue error: " + ex.getMessage());
return null;
}
return lsAttrValue;
}
/**************************************************************************
*<p>功能: 解析所有消息共有的节点和属性</p>
*@parameters:
*@returns: boolean 成功 true 失败 false
***************************************************************************/
public boolean getPubNodesValue() {
NodeList loNodeList;
Node loNode;
Element loElement;
String lsNodeValue,lsAttrValue;
try {
loNodeList = ioDoc.getElementsByTagName(UserInfo);
if (loNodeList.getLength() <= 0) {
throw new Exception("Can't get message header from XML data.");
}
loElement = (Element) loNodeList.item(0);
//解析属性
lsAttrValue = loElement.getAttribute(UserName).trim();
… … …
}
当然,也可以象使用解析INI文件的方法一样,用遍历的方法来实现。
本文是某通信服务项目中的一部分,全部程序均在Windows2000环境中JBuilder6.0下调试通过,并在SUN Solaris5.7环境下运行。
|