猛禽洛的程式筆記庫

[Java] 使用Apache Commons CSV來讀寫CSV資料

維基百科:

CSV是一種分隔的文字檔案,它使用逗號來分割值(許多CSV匯入/匯出工具的實現也允許使用其它的分隔符)。簡單的CSV實現可以禁止欄位值中包含逗號或其它特殊字元如換行符。更複雜的CSV實現允許這些特殊字元,它們往往要求用”(雙引號)包裹這些包含保留字元(如逗號、雙引號或不太通用的換行符)的數值。被嵌入的雙引號字元可以用連續兩個雙引號來表示(Creativyst 2010),或者使用跳脫字元反斜槓(例如在Sybase Central中)。

在電腦科學術語中,CSV檔案可以被認為是一個「平面檔案資料庫」。

簡單來說,就是可以當作輕量資料儲存的方式,一種架構非常簡單的資料庫。

 

在這篇文章中,會用來儲存感測計的資料,將感測器資料儲存與取出,方便用作歷史紀錄圖表顯示。

1.導入maven: Apache Commons CSV

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-csv -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-csv</artifactId>
  <version>1.8</version>
</dependency>

 

2.如何寫入CSV檔:

//如果是第一次建檔
//CSV的格式設定,使用\n作為換行標誌,並且第一行是Header(欄位標題)
CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator("\n").withHeader({"time", "value"});
//建立FileWriter物件("檔案路徑", "是否接續寫入")
FileWriter csvWriter = new FileWriter("File檔案路徑", true);
//建立CSVPrinter物件
printer = new CSVPrinter(csvWriter, format);

//寫入一筆資料
printer.printRecord("1135", "20");
//完成寫入(怕傷flash的話就結束寫入此檔案時再使用)
printer.flush();

//如果是之後要接續寫入,會有第一行是Header的問題,需要避開他才不會增加了兩行Header
//我的方法是在建立CSVFormat時,判斷檔案是否存在,存在就withSkipHeaderRecord
if("File檔案路徑".isFile()){//檔案已存在,跳過Header處理
  format = CSVFormat.DEFAULT.withRecordSeparator("\n").withHeader(csvHeader).withSkipHeaderRecord();
}else{
  format = CSVFormat.DEFAULT.withRecordSeparator("\n").withHeader(csvHeader);
}

//最後,記得關閉資料流
try{
  if(csvWriter != null){
    csvWriter.flush();
    printer.close(true);
    csvWriter.close();
    csvWriter = null;
    printer = null;
    System.out.println("寫檔已停止");
  }
} catch (IOException e) {
  e.printStackTrace();
}

 

3.如何讀取CSV檔:

//定義Header有哪些元素
private String[] csvHeader = new String[]{"time", "value"};
try{
  Reader reader = Files.newBufferedReader(Paths.get("檔案路徑String"));
  CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT
      .withFirstRecordAsHeader()//第一筆紀錄是Header
      .withIgnoreHeaderCase()
      .withTrim());

  //CSV是一行一行往下讀的,沒辦法跳著讀
  for (CSVRecord csvRecord : csvParser) {
    // Accessing values by Header names
    //取得某欄位資料
    String readTime = csvRecord.get(csvHeader[0]);
    String readValue = csvRecord.get(csvHeader[1]);

    //讀到的資料就可以在這邊存起來
    xxx.put(readValue);
  }
  //記得關閉資料流
  csvParser.close();
} catch (IOException e) {
  e.printStackTrace();
}

 

在讀取中小量資料時,Apache Commons CSV就夠用了,但是如果讀取大量資料(幾十萬以上),可能就會明顯感到效率低。

這時可以用 FastCSV 來做讀取

https://github.com/osiegmar/FastCSV

日後再補上教學內容。

 

–END–

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *