解析Txt文件的过程

解析Txt文件的过程

项目需要解析用逗号(,)分隔的文本文件,然后将其中的数据转换成xml文件进行导入到财务系统中....
考虑到以后可能文件格式会变化,因此使用了动态的创建方法,即通过格式文件来动态解析txt文件..本程序使用了apache的Digester来动态生成格式文件,使用CGLib动态生成目标类.步骤如下:
1、定义文件和字段的元数据格式,如果出现其他的文件格式只需要实现元数据接口即可..接口代码:
java 代码
  1. public interface FileMeta {
  2. public String getName();
  3. public List<fieldmeta></fieldmeta> getFieldMeta();
  4. }
  5. public interface FieldMeta {
  6. public String getName();
  7. public String getType();
  8. public int getLength();
  9. public int getScale();
  10. public String getComment();
  11. public boolean isAllowNull();
  12. }
通过两个接口描述文件的属性已经字段格式..

本例使用的是逗号分隔,如果出现其他分隔符怎么办?为此,定义了一个分隔符接口:LineSpliter
java 代码
  1. public interface LineSpliter {
  2. public String getSpliterRegx();
  3. public String[] split(String lineData);
  4. }
getSpliterRegx()同于返回当前的分隔符,split()用户处理各行文本数据.
此处缺省实现了此接口,用于逗号分隔DefaultLineSpliter,定义如下:
java 代码
  1. public class DefaultLineSpliter implements {
  2. public String defaultSpliterRegx = ",";
  3. public String getSpliterRegx() {
  4. return defaultSpliterRegx ;
  5. }
  6. public String[] split(String lineData) {
  7. return StringUtils.splitPreserveAllTokens(lineData,defaultSpliterRegx );
  8. }
  9. }
这里使用apache的Lang包进行处理,没有使用JDK的String的split方法,因为jdk的实现会将末尾空的字段过滤掉,造成数据减少...
比如:如果行数据为aaa,bbb,,,,, 通过jdk的实现会返回aaa和bbb,而通过Lang包处理会返回包括后面空的字段.

2、接下来使用DigesterDigester包根据xml规则生成对象..
首先需要了解digester包的使用方法,这里简单的说一下:disgeter可以根据一定的规则将xml文件解析成一组对象...具体这里,我先定义
一个规则文件,
xml 代码
  1. <digester-rules>
  2. <pattern value='XXXFileMeta'>
  3. <object-create-rule classname="com.xxx.file.DefaultFileMeta"/>
  4. <set-properties-rule/>
  5. <pattern value="field">
  6. <object-create-rule classname="com.xxx.file.DefaultFieldMeta"/>
  7. <set-properties-rule/>
  8. <bean-property-setter-rule pattern="beanname1"/>
  9. <bean-property-setter-rule pattern="beanname2"/>
  10. <bean-property-setter-rule pattern="beanname3"/>
  11. <bean-property-setter-rule pattern="beanname4"/>
  12. <!---->pattern>
  13. <!---->digester-rules>
这就是一个简单的规则定义,具体含义这里不详细讲了,想了解的可以给我回帖...
接着定义缺省的文件元数据文件,格式如下:
xml 代码
 
  1. <DefaultFileMeta name="com.xxx.file.DefaultFileMeta">  
  2.     <field>  
  3.         <beanname1>Codebeanname1>  
  4.         <beanname2>Namebeanname2>  
  5.         <beanname3>Datebeanname3>  
  6.         <beanname4>Remakebeanname4>  
  7.     field>  
  8. DefaultFileMeta>  

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

代码如下:GeneratorObject.createObject(){}
初始化CGLib
java 代码
  1. @SuppressWarnings("unchecked")
  2. private void init(Class target, FileMeta fileMeta) {
  3. List<fieldmeta></fieldmeta> fields = fileMeta.getFieldMeta();
  4. String[] getters = new String[fields.size()];
  5. String[] setters = new String[fields.size()];
  6. Class[] types = new Class[fields.size()];
  7. try {
  8. for (int i=0; i < fields.size(); i++) {
  9. FieldMeta fieldMeta = fields.get(i);
  10. getters[i] = "get" + ConverterUtils.upperCaseFirstChar(fieldMeta.getName());
  11. setters[i] = "set" + ConverterUtils.upperCaseFirstChar(fieldMeta.getName());
  12. types[i] = Class.forName(fieldMeta.getType());
  13. }
  14. } catch(ClassNotFoundException e) {
  15. logger.error("类没有找到.." + e.getMessage());
  16. }
  17. this.bulkBean = BulkBean.create(target, getters, setters, types);
  18. }
根据指定的目标类动态生成对象
java 代码
  1. @SuppressWarnings("unchecked")
  2. private Object createObject(Class target, FileMeta fileMeta, Object[] values) {
  3. Object targetObject = null;
  4. try {
  5. targetObject = target.newInstance();
  6. } catch (Exception e){
  7. logger.error("创建对象出错,目标类-->" + target.getName(), e);
  8. }
  9. bulkBean.setPropertyValues(targetObject, values);
  10. return targetObject;
  11. }
解析文本文件
java 代码
  1. @SuppressWarnings("unchecked")
  2. public List createObjects() {
  3. //初始化BulkBean
  4. init(targetClass, fileMeta);
  5. List result = new ArrayList();
  6. LineIterator iterator = null;
  7. try {
  8. iterator = FileUtils.lineIterator(this.dataFile, DEF_ENCODING);
  9. while(iterator.hasNext()) {
  10. String line = iterator.nextLine();
  11. //过滤掉数据文件中的空行
  12. if (StringUtils.isBlank(line)) {
  13. continue;
  14. }
  15. Object[] values = this.parseLine(line, fileMeta);
  16. Object object = createObject(this.targetClass, fileMeta, values);
  17. result.add(object);
  18. }
  19. } catch (IOException e) {
  20. logger.error("读取文件名出错!-->" + this.dataFile.getName(), e);
  21. } finally {
  22. LineIterator.closeQuietly(iterator);
  23. }
  24. return result;
  25. }
最终返回解析好的文本文件对象列表..
本例综合使用了apache的代码包,灵活实现了文本文件的解析...

你可能感兴趣的:(spring,jdk,bean,xml,百度)