从事互联网金融,常常会碰到文件处理,以前都是傻傻的解析,这次我不想这么傻了,做个小小的封装,咱也以oop的思想来完成。
文件解析处理一般分两种模式:分隔符与定长,目前工作五年也就这两种。
封装思想:
- 分隔符模式采用反射转换为对象
- 室长模式采用反射加注解转换为对象
1 package anno; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 /** 9 * @author wujf 文件转对象注解 10 */ 11 @Retention(RetentionPolicy.RUNTIME) 12 @Target({ ElementType.FIELD, ElementType.PARAMETER }) 13 public @interface Fto { 14 String desc() default ""; 15 16 int len() default 0; 17 }
1 package anno; 2 3 import java.lang.reflect.Field; 4 5 public class FtoAnnoImp { 6 7 /** 8 * 根据分隔符转换 9 * 10 * @param str 11 * @param split 12 * @param cls 13 * @return 14 * @throws Exception 15 */ 16 public static Object parseWithSplit(String str, String split, Class cls) throws Exception { 17 Object obj = cls.newInstance(); 18 Field[] fields = cls.getDeclaredFields(); 19 String[] tem = str.split(split); 20 for (int i = 0; i < tem.length; i++) { 21 fields[i].set(obj, tem[i]); 22 } 23 return obj; 24 } 25 26 /** 27 * 根据定长转换 28 * 29 * @param str 30 * @param cls 31 * @return 32 * @throws Exception 33 */ 34 public static Object parseWithLen(String str, Class cls) throws Exception { 35 Object obj = cls.newInstance(); 36 Field[] fields = cls.getDeclaredFields(); 37 Fto fto; 38 int idx = 0; 39 for (int i = 0; i < fields.length; i++) { 40 fto = fields[i].getAnnotation(Fto.class); 41 int len = fto.len(); 42 fields[i].set(obj, str.substring(idx, idx + len)); 43 idx = idx + len; 44 } 45 return obj; 46 } 47 }
下面上一段测试代码
1 package anno; 2 3 public class FtoObj { 4 5 @Fto(desc = "AA", len = 2) 6 public String A; 7 @Fto(desc = "BB", len = 2) 8 public String B; 9 10 @Override 11 public String toString() { 12 return "FtoObj [A=" + A + ", B=" + B + "]"; 13 } 14 15 }
1 package anno; 2 3 /** 4 * @author 5 */ 6 public class TestFto { 7 public static void main(String[] args) throws Exception { 8 String s = "32123234234123412,fsjkadfjdkasjf"; 9 FtoObj obj = (FtoObj) FtoAnnoImp.parseWithSplit(s, ",", FtoObj.class); 10 System.out.println(obj.toString()); 11 s = "1234"; 12 obj = (FtoObj) FtoAnnoImp.parseWithLen(s, FtoObj.class); 13 System.out.println(obj.toString()); 14 } 15 }
后续建议
1、由于文件一行行读取,因此建议读取的结果建议放在一个list里,list定义如下哦!(如果是大文件,记得分多次转list,不然内存有压力的)
1 package anno; 2 3 import java.util.List; 4 5 public class FtoList { 6 public int lineNo; 7 public List<Object> object; 8 }
2、注解里可以定义的更加丰富,比如支持类型(int、date),目前写的简单,统一当字符串处理了,后续业务处理还可能涉及类型转换