網際網路金融專案——工作日誌(六)玩轉檔案讀取
換了新工作,部落格停了幾個星期,重新開始堅持碼部落格~不總結,就像出門不穿衣服,彆扭的不行。
最近花兩週做的一個專案,主要是對第三方傳送過來的核心資料進行合併、校驗、加密、壓縮、生成明文,密文的過程。
傳送資料採用的檔案開始使用.xlsx格式,特點就是3個月資料,按月拆分,多個sheet,資料量大,採用POI的操作模式。windows 系統6g的記憶體,依然會被跑爆。
後來應我方需求,按天拆分,分成3種格式的報文,給我們的格式變成了.cvs,後來又變成了.txt。
為什麼要進行格式的改變?
首先介紹一下這三種檔案格式的特徵。
.xlsx: excel副檔名,基於新的xml檔案壓縮格式,包含book,sheet,cell等單元,可以通過POI直接進行office文件操作。
.csv: 逗號分隔值(Comma-Separated Values),檔案以純文字形式儲存表格資料。比如用txt檔案開啟,就是一行一條記錄,以逗號分割。
.txt: 文字格式,儲存文字資訊,體積小,儲存簡單,格式通用,不會中毒。
從特殊到普通是創造。為了能試用於更多的檔案格式,我們採用了最最基礎的.txt檔案,這樣可以把這三種格式的檔案,都轉換成文字檔案,以逗號分割,記錄資料資訊的形式。進行讀取,逐行解析和組裝,一站式的操作,可以應對更多的變化。
通過IO讀取檔案,合併
/** * 讀取檔案所有行資訊 * @param fileName 檔案路徑名稱 例如:D:\\CreateFile\\20160705_1_123.txt; * @return 檔案內容 */ public static List<String> readAllLines(String fileName){ List<String> cardInfoList=new ArrayList<String>(); try { @Cleanup BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), StandardCharsets.UTF_8));//換成你的檔名 String line = null; while((line=reader.readLine())!=null){ cardInfoList.add(line); } } catch (Exception e) { e.printStackTrace(); } return cardInfoList; } public static void writeAllLines(String fileName, List<String> listLines){ if(listLines == null || listLines.size() == 0) return ; try { @Cleanup BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), StandardCharsets.UTF_8));//換成你的檔名 int count = 0; for (String line:listLines) { if(line != null) { writer.write(line); count ++; if(count != listLines.size()) writer.write("\r\n"); } } writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); } }
獲取.txt為字尾的所有檔案,獲取整個檔名(含路徑) / 獲取檔名(不含路徑)
String plainFilePath = "D:\\job\\codeSource\\data\\plain\\";
File file = new File(plainFilePath);
File[] tempList = file.listFiles();
List<String> listFile = new ArrayList<String>();
String fileName ;
for (int i = 0; i < tempList.length; i++) {
fileName = tempList[i].toString();
if(!fileName.substring(fileName.length() - 3).equals("txt"))//獲取字尾為.txt為字尾的所有檔案
continue;
listFile.add(tempList[i].toString());
}
String holeFilePath ;
String partFilePath ;
CreditMessage message = new CreditMessage();
//讀取明文內容,並解析成message
for (int j = 0; j < listFile.size(); j++) {
holeFilePath = listFile.get(j);//獲取整個檔案路徑+檔名
partFilePath = holeFilePath.substring(holeFilePath.lastIndexOf("\\") + 1, holeFilePath.lastIndexOf("."));//獲取檔名
}
Byte陣列的擷取
/**
* 獲取頭string字串
* @param Length 擷取長度
* @param start 擷取初始位置
* @param end 擷取終止位置
* @param creditMessageHead 擷取字串
* @return 擷取字串
*/
private static String getMessageHeadMessge(int Length, int start, int end, byte[] creditMessageHead){
byte[] strDataVersion=new byte[Length];
for(int i =start;i<end;i++){
strDataVersion[i-start]=creditMessageHead[i];
}
String str=null;
try{
str=new String (strDataVersion,"GB18030").trim();
}catch (Exception e){
e.printStackTrace();
}
return str ;
}
列舉的使用
//列舉定義
@Getter
public enum ItemIdentityEnum {
CREDIT_AMOUNT("9100", "授信額度", DataType.N, 10, true),
SHARE_CREDIT_AMOUNT("9101", "共享授信額度", DataType.N, 10, true),
//識別符號
private String code;
//資料項名稱
private String name;
//型別
private DataType type;
//長度
private int length;
//是否必填
private boolean required;
ItemIdentityEnum(String code, String name, DataType type, int length, boolean required) {
this.code = code;
this.name = name;
this.type = type;
this.length = length;
this.required = required;
}
}
//列舉取值
ItemIdentityEnum.CREDIT_AMOUNT.getLengt();
//列舉賦值
public CreditMessageBaseSegment setBusinessCategory(BusinessCategoryEnum value) {
businessCategory.setValue(value);
return this;
}
異常的使用
public static void writeLogFile(Exception e,String businessNo){
try{
FileWriter fileWriter=null;
//建立檔案的輸出流
fileWriter=new FileWriter("D:\\error\\error.txt",true);
fileWriter.write("\r\n"+e+"\r\n"+"業務號:"+businessNo+"\r\n");
fileWriter.close();
}
catch(Exception s){
s.printStackTrace();
}
}
專案比較小,用時2周,最終達到的效果是,能讀取各種型別檔案,校驗過程中無需叫停,一站記錄所有錯誤日誌,明文生成、校驗、壓縮解耦合,避免了操作之間的干擾。
這是新公司的第一個入手專案,執行結果,很讓人激動興奮,很開心能跟如此優秀的人一起共事,進步。感恩所經歷的一切人和事~