猛禽洛的程式筆記庫

[Android] 讀取大檔資料的技巧與注意事項

這個想法來自有一次需要處理大檔案的數據資料(CSV),檔案內容有10萬行*數百欄位,在使用kotlin-csv套件讀進程式中後,就觸發了outOfMemory!,沒錯,記憶體炸啦!

//開啟輸入流
val inputStream = contentResolver.openInputStream(projectDocumentFiles.rawData.uri)
//用kotlin-csv套件開啟csv檔
listLeftData = csvReader().readAll(inputStream)

仔細慢慢分析後,發現List格式非常吃記憶體,csv讀近來後通通用List<List<String>>存,雖然方便,但炸掉的話就沒搞頭啦!

所以對於這種大型資料讀取,我選擇自己做最佳化。

首先分析檔案內容,我的csv內都是儲存數字,所以我們的變數就以float Array為主要儲存方式,並且每行資料再由List來儲存,記憶體就不會吃到這麼重。

另外讀取方式也要一次讀一行,節省處理過程中的記憶體占用!

//取得輸入流
val inputStream = contentResolver.openInputStream(projectDocumentFiles.rawData.uri)
//用BufferedReader讀取
val reader = BufferedReader(InputStreamReader(inputStream))
//大檔讀取,省記憶體,會自動關閉io
reader.forEachLine {
  //切割資料
  val tmpValues = it.split(",")
  //建立float陣列
  val dataArray = FloatArray(tmpValues.size)
  for(value in 0 until tmpValues.size){
    //將檔案中的值轉為數值
    dataArray[value] = tmpValues[value].toFloat()
  }
  //將資料放進MutableList<FloatArray>中
  mutableListData.add(dataArray)
}

這樣實測下來,原本要吃600多MB的記憶體,可以下降至230MB左右!

雖然處理過程中複雜了一些,但一開始將資料都轉換好,也有助於之後的資料處理!~

 

-END-

發佈留言

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