首頁 >Java >java教程 >Java讀取大檔案記憶體溢位的解決辦法

Java讀取大檔案記憶體溢位的解決辦法

黄舟
黄舟原創
2017-08-10 09:21:332614瀏覽

下面小編就為大家帶來一篇完美解決java讀取大檔案記憶體溢出的問題。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧

1. 傳統方式:在記憶體中讀取檔案內容

讀取檔案行的標準方式是在記憶體中讀取,Guava 和Apache Commons IO都提供瞭如下所示快速讀取文件行的​​方法:


Files.readLines(new File(path), Charsets.UTF_8); 
FileUtils.readLines(new File(path));

實際上是使用BufferedReader或者其子類別LineNumberReader來讀取的。

傳統方式的問題: 是檔案的所有行都被存放在記憶體中,當檔案夠大時很快就會導致程式拋出OutOfMemoryError 異常。

問題思考:我們通常不需要把檔案的所有行一次性放入記憶體中,相反,我們只需要遍歷檔案的每一行,然後做相應的處理,處理完之後把它丟掉。所以我們可 以透過行迭代方式來讀取,而不是把所有行都放在記憶體中。

2. 大檔案讀取處理方式

#不重複讀取與不耗盡記憶體的情況下處理大檔案:

(1)檔案流方式:使用java.util.Scanner類別掃描檔案的內容,一行一行連續讀取


FileInputStream inputStream = null; 
Scanner sc = null; 
try { 
 inputStream = new FileInputStream(path); 
 sc = new Scanner(inputStream, UTF-8); 
 while (sc.hasNextLine()) {
  String line = sc.nextLine(); 
  // System.out.println(line); 
  } 
}catch(IOException e){
  logger.error(e);
}finally {
  if (inputStream != null) { 
  inputStream.close(); 
  } 
  if (sc != null) {
    sc.close();
   }
}

該方案將會遍歷檔案中的所有行,允許對每一行進行處理,而不保持對它的參考。 總之沒有把它們存放在記憶體中!

(2)Apache Commons IO流:使用Commons IO庫實現,利用該庫提供的自訂LineIterator


LineIterator it = FileUtils.lineIterator(theFile, UTF-8); 
try {
 while (it.hasNext()) {
 String line = it.nextLine(); 
 // do something with line 
  } 
} finally {
 LineIterator.closeQuietly(it);
}

此方案由於整個檔案不是全部存放在記憶體中,這也就導致相當保守的記憶體消耗。

以上是Java讀取大檔案記憶體溢位的解決辦法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn