您的位置:首页 > 其它

解析Txt文件的过程

2009-07-13 13:11 246 查看
解析Txt文件的过程

项目需要解析用逗号(,)分隔的文本文件,然后将其中的数据转换成xml文件进行导入到财务系统中....

考虑到以后可能文件格式会变化,因此使用了动态的创建方法,即通过格式文件来动态解析txt文件..本程序使用了apache的Digester来动态生成格式文件,使用CGLib动态生成目标类.步骤如下:

1、定义文件和字段的元数据格式,如果出现其他的文件格式只需要实现元数据接口即可..接口代码:

java 代码

public

interface
FileMeta {

public
String getName();

public

List<fieldmeta></fieldmeta> getFieldMeta();

}

public

interface
FieldMeta {

public
String getName();

public
String getType();

public

int
getLength();

public

int
getScale();

public
String getComment();

public

boolean
isAllowNull();

}

通过两个接口描述文件的属性已经字段格式..

本例使用的是逗号分隔,如果出现其他分隔符怎么办?为此,定义了一个分隔符接口:LineSpliter

java 代码

public

interface
LineSpliter {

public
String
getSpliterRegx();

public
String[]
split(String lineData);

}

getSpliterRegx()同于返回当前的分隔符,split()用户处理各行文本数据.

此处缺省实现了此接口,用于逗号分隔DefaultLineSpliter,定义如下:

java 代码

public

class
DefaultLineSpliter
implements
{

public
String
defaultSpliterRegx =
","
;

public
String
getSpliterRegx() {

return
defaultSpliterRegx ;

}

public
String[] split(String
lineData) {

return

StringUtils.splitPreserveAllTokens(lineData,defaultSpliterRegx );

}

}

这里使用apache的Lang包进行处理,没有使用JDK的String的split方法,因为jdk的实现会将末尾空的字段过滤掉,造成数据减少...

比如:如果行数据为aaa,bbb,,,,,
通过jdk的实现会返回aaa和bbb,而通过Lang包处理会返回包括后面空的字段.

2、接下来使用DigesterDigester包根据xml规则生成对象..

首先需要了解digester包的使用方法,这里简单的说一下:disgeter可以根据一定的规则将xml文件解析成一组对象...具体这里,我先定义

一个规则文件,

xml 代码

<
digester-rules
>

<
pattern

value
=
'XXXFileMeta'
>

<
object-create-rule

classname
=
"com.xxx.file.DefaultFileMeta"
/>

<
set-properties-rule
/>

<
pattern

value
=
"field"
>

<
object-create-rule

classname
=
"com.xxx.file.DefaultFieldMeta"
/>

<
set-properties-rule
/>

<
bean-property-setter-rule

pattern
=
"beanname1"
/>

<
bean-property-setter-rule

pattern
=
"beanname2"
/>

<
bean-property-setter-rule

pattern
=
"beanname3"
/>

<
bean-property-setter-rule

pattern
=
"beanname4"
/>

pattern
>

digester-rules
>

这就是一个简单的规则定义,具体含义这里不详细讲了,想了解的可以给我回帖...

接着定义缺省的文件元数据文件,格式如下:

xml 代码

<
DefaultFileMeta

name
=
"com.xxx.file.DefaultFileMeta"
>

<
field
>

<
beanname1
>
Code
beanname1
>

<
beanname2
>
Name
beanname2
>

<
beanname3
>
Date
beanname3
>

<
beanname4
>
Remake
beanname4
>

field
>

DefaultFileMeta
>

最后实例化digester对象,加载规则文件,解析文件元数据文件,则会动态生成根据元数据文件解析的格式定义.

代码如下:GeneratorObject.createObject(){}

初始化CGLib

java 代码

@SuppressWarnings
(
"unchecked"
)

private

void
init(Class target, FileMeta fileMeta) {

List<fieldmeta></fieldmeta> fields =
fileMeta.getFieldMeta();

String[] getters = new

String[fields.size()];

String[] setters = new

String[fields.size()];

Class[] types = new

Class[fields.size()];

try
{

for
(
int
i=
0
; i
< fields.size(); i++) {

FieldMeta fieldMeta = fields.get(i);

getters[i] = "get"
+
ConverterUtils.upperCaseFirstChar(fieldMeta.getName());

setters[i] = "set"
+
ConverterUtils.upperCaseFirstChar(fieldMeta.getName());

types[i] = Class.forName(fieldMeta.getType());

}

} catch
(ClassNotFoundException e) {

logger.error("类没有找到.."
+
e.getMessage());

}

this
.bulkBean =
BulkBean.create(target, getters, setters, types);

}

根据指定的目标类动态生成对象

java 代码

@SuppressWarnings
(
"unchecked"
)

private
Object
createObject(Class target, FileMeta fileMeta, Object[] values) {

Object targetObject = null
;

try
{

targetObject = target.newInstance();

} catch
(Exception e){

logger.error("创建对象出错,目标类-->"
+ target.getName(), e);

}

bulkBean.setPropertyValues(targetObject, values);

return
targetObject;

}

解析文本文件

java 代码

@SuppressWarnings
(
"unchecked"
)

public
List createObjects()
{

//初始化BulkBean

init(targetClass, fileMeta);

List result = new

ArrayList();

LineIterator iterator = null
;

try
{

iterator = FileUtils.lineIterator(this
.dataFile, DEF_ENCODING);

while
(iterator.hasNext()) {

String line = iterator.nextLine();

//过滤掉数据文件中的空行

if

(StringUtils.isBlank(line)) {

continue
;

}

Object[] values = this
.parseLine(line, fileMeta);

Object object = createObject(this
.targetClass, fileMeta, values);

result.add(object);

}

} catch
(IOException e) {

logger.error("读取文件名出错!-->"

+
this
.dataFile.getName(), e);

} finally
{

LineIterator.closeQuietly(iterator);

}

return
result;

}

最终返回解析好的文本文件对象列表..

本例综合使用了apache的代码包,灵活实现了文本文件的解析...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: