通常获取支付公司对账文件的时候,有时候会给到.csv数据文件,考虑到如果对账文件里面数据量多,一次获取到所有数据,会导致内存溢出,这里借鉴 easyExcel 监听方式分批读取数据,但方式略有不同,思路是 逐行读取,添加到list中去,当list到达指定长度后,进入入库操作,并清空list,避免一次加载到list中去。
照例我们先看官网,如何读取数据,如图,数据方式,注解方式
这里采用数组方式处理,首先引用 maven 组件
com.opencsv
opencsv
4.6
具体代码:单批次最大数量 private int SIZE = 1000 ;
/**
* 读取 对账 csv 文件
* path 文件路径
* checkDt 对账日期
* @param path
*/
public void readCsv(String path, String checkDt) {
try {
DataInputStream in = new DataInputStream(new FileInputStream(new File(path)));
CSVReader csvReader = new CSVReader(new InputStreamReader(in, "utf-8"), CSVParser.DEFAULT_SEPARATOR,
CSVParser.DEFAULT_QUOTE_CHARACTER, CSVParser.DEFAULT_ESCAPE_CHARACTER, 1);
String[] strs;
List list = new ArrayList<>();
CheckTransInfoDto dto = null;
int i = 0;
while ((strs = csvReader.readNext()) != null) {
//System.out.println(Arrays.deepToString(strs));
dto = new CheckTransInfoDto();
// 将数据数据设置到实体对象中去
list.add(setData(strs,dto));
i++;
// 当 list 到达单批次最大数量后,执行保存数据操作,并清空list
if (i==SIZE){
checkTransInfoMapper.saveCheckTransInfo(list,checkDt);
list.clear();
i = 0;
}
}
// 跳出循环后,判断里面有没有数据 防止有数据遗漏
if (null!=list&&list.size()>0){
checkTransInfoMapper.saveCheckTransInfo(list,checkDt);
}
// 关闭流
csvReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
将数组里面的数据设置到实体对象中
/**
* 设置对账实体信息
* @param strs
* @param dto
* @return
*/
public CheckTransInfoDto setData(String[] strs,CheckTransInfoDto dto){
dto.setTransOrderNo(strs[0].trim());
dto.setTransMercId(strs[1].trim());
dto.setSmtMercId(strs[2].trim());
dto.setCrdNo(strs[3].trim());
dto.setCrdFlg(strs[4].trim());
dto.setTxnCd(strs[5].trim());
dto.setOrderTyp(strs[6].trim());
dto.setSmtTyp(strs[7].trim());
dto.setDepositTransFlag(strs[8].trim());
dto.setActiveTransFlag(strs[9].trim());
dto.setTxnAmt(strs[10].trim());
// ...
//System.out.println(dto.toString());
return dto;
}
保存数据的方法这里不再写,思路就是逐行读取添加到list中去,当list中数据达到单批次最大量后,保存数据,清空list ,直到读取完所有信息,这样避免逐行读取保存数据速度过慢,大数据量读取导致内存溢出的问题。写的比较浅显,如果错误,请指出,谢谢