一、背景
在日常开发中经常会遇到,从数据库导出一批离线数据,然后通过程序清洗转换为结果文件。
在本示例中我导出了一般mysql表的主键, 然后对主键的行记录进行修改,需要逐条生成备份sql及更更新sql。
环境:离线数据是csv文件;结果文件需要是sql文件;操作语言是java;
二、示例
public void fileConvert() {
FileReader reader = null;
BufferedWriter bufferedWriter = null;
try {
//加载文件
String fundChannelCode = "TEST";
String infilePath = "/data/bank_fails/" + fundChannelCode + "/" + fundChannelCode + ".csv";
String outfilePath = "/data/bank_fails/" + fundChannelCode + "/" + fundChannelCode + "_update_auth.sql";
File inFile = new File(infilePath);
File outFile = new File(outfilePath);
FileReader rde = new FileReader(inFile);
BufferedReader bufferedReader = new BufferedReader(rde);
StringBuilder inStr = new StringBuilder();
String backupStr = "SELECT status,id from tt_test WHERE id in ('%s') AND status ='F' limit 1 ;";
String updateStr = "update tt_test set status='T' WHERE id in ('%s') AND status ='2' limit 1 ;";
String lineStr = null;
while ((lineStr = bufferedReader.readLine()) != null) {
//备份sql
inStr.append(String.format(backupStr, lineStr)).append("\n");
//更新sql
inStr.append(String.format(updateStr, lineStr)).append("\n");
}
bufferedWriter = new BufferedWriter(new FileWriter(outFile));
bufferedWriter.write(inStr.toString());
//缓存刷数据到文件这一步一定不能少,否则可能导致结果文件内容缺失
bufferedWriter.flush();
} catch (Exception e) {
System.out.println("nn" + e.getMessage());
} finally {
try {
reader.close();
bufferedWriter.close();
} catch (Exception e) {
}
}
}
注意:
1)该示例中原始文件、目标文件都是逐行的, 所以选择的是BufferedReader、BufferedWriter 读写数据,如果数据中没有/r 或/n的换行符,不能用用它们来读写数据;
2)使用流读写数据后, 一定记得关闭数据流
3)BufferedWriter 将数据往文件里面写的时候,一定需要 bufferedWriter.flush();将缓存区的数据刷新到文件,否则会导致缓存区的文件还未完全写入到目标文件,但是我们线程已经关了,终止写的操作,从而出现掉数据的情况;
4)在bufferedReader.readLine() 读取数据的时候,一定要注意每运行一次该代码, 读取文件的下标会向前挪动一次;如果在同一个操作中重复执行该代码会导致数据缺失;