解析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 > Code beanname1 >   
  4.         < beanname2 > Name beanname2 >   
  5.         < beanname3 > Date beanname3 >   
  6.         < beanname4 > Remake beanname4 >   
  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的代码包,灵活实现了文本文件的解析...

你可能感兴趣的:(解析Txt文件的过程)