一、背景
在日常開發中經常會遇到,從數據庫導出一批離線數據,然後通過程序清洗轉換爲結果文件。
在本示例中我導出了一般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() 讀取數據的時候,一定要注意每運行一次該代碼, 讀取文件的下標會向前挪動一次;如果在同一個操作中重複執行該代碼會導致數據缺失;