解析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的代碼包,靈活實現了文本文件的解析...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章