解析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>Codebeanname1>
- <beanname2>Namebeanname2>
- <beanname3>Datebeanname3>
- <beanname4>Remakebeanname4>
- 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() {
-
- 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的代码包,灵活实现了文本文件的解析...