背景
因公司需要同步银联交易流水文件数据,Java后端需要定时解析文件,并将记录更新到mysql数据库。为方便存取数据,所以编写以下代码供大家参考。
/**
* 规则对象,格式化数据
*/
@Data
public class FieldFormatDef {
private Integer seq;//序号
private String name;//名称
private String field;//字段名
private Integer length;//字段总长度(用于截取)
private Integer startIdx;//开始下标(用于截取)
private Integer endIdx;//结束下标(用于截取)
/**
* 获取某一行,某一列的值
* @param line 单行数据
* @return
*/
public String getValue(String line){
return line.substring(startIdx,endIdx).trim();
}
}
/**
* 文件处理类
*/
public class CupsFileDef {
private Map<String,FieldFormatDef> map = new HashMap<>();
/**
* 根据字段名和行数据,获取具体的值
* @param key 字段名
* @param line 行数据
* @return
*/
public String getFieldValue(String key,String line){
FieldFormatDef def = map.get(key);
return def.getValue(line);
}
/**
* 添加规则对象
* @param field 字段名
* @param name 名称
* @param seq 序号
* @param length 获取的长度
* @param before 上一个规则对象
* @return 返回当前添加的规则对象
*/
public FieldFormatDef add(String field,String name,Integer seq,Integer length,FieldFormatDef before){
FieldFormatDef def = new FieldFormatDef();
def.setField(field);
def.setName(name);
def.setSeq(seq);
def.setLength(length);
//before为空则表示为第一列的值
if(before == null){
//设置截取的开始下标
def.setStartIdx(0);
//设置截取的结束下标
def.setEndIdx(length);
}else{
//不是第一列的值
//取上个规则的结束下标+1
def.setStartIdx(before.getEndIdx() + 1);
//结束下标:开始下标+字段总长度
Integer endIdx = def.getStartIdx() + def.getLength();
def.setEndIdx(endIdx);
}
//保存到当前对象的map集合
map.put(def.getField(),def);
return def;
}
/**
* 获取文件处理类
* @return
*/
public static CupsFileDef getDef(){
//添加规则
CupsFileDef comFile = new CupsFileDef();
FieldFormatDef def = comFile.add("agent_branch_code", "代理机构标识", 1, 11, null);
def = comFile.add("send_branch_code", "发送机构标识", 2, 11, def);
def = comFile.add("sys_track_no", "系统跟踪号", 3, 6, def);
def = comFile.add("trans_time", "交易传输时间", 4, 10, def);
def = comFile.add("account", "主账号", 5, 19, def);
def = comFile.add("amount", "交易金额", 6, 12, def);
//因为银联文件里面有些数据是我们不需要的,所以我们不定义它,但还是要占个位置
def = comFile.add("7", "7", 7, 12, def);
def = comFile.add("8", "8", 8, 12, def);
def = comFile.add("message_type", "报文类型", 9, 4, def);
return comFile;
}
public static void main(String args[]){
CupsFileDef comFile = CupsFileDef.getACOMDef();
//读取银联文件,PS:因为银联过来的文件是.Z类型的,解压后无后缀,所以读取的文件路径是无后缀文件
List<String> readLines = FileUtil.readLines(new File("D:\\银联对账文件\\IND20021701ACOM"), "utf-8");
//FileUtil用的是huttol里面的文件工具类,没有的需要引入一下
for (String line : readLines) {
String agentBranchCode = comFile.getFieldValue("agent_branch_code", line);
String sendBranchCode = comFile.getFieldValue("send_branch_code", line);
String sysTrackNo = comFile.getFieldValue("sys_track_no", line);
//...
String amount = comFile.getFieldValue("pay_fee", line);
}
//实际操作中,直接将数据取出来后,做些简单的业务逻辑后,直接存数据库就O了
}
}