這篇文章主要是講解展現,在Java中如何高效的讀取大文件中的數據。html
通常狀況下,咱們都是在內存中讀取文件——Guava 和 Apache Commons IO 提供了快速的方法:
java
Files.readLines(new File(path), Charsets.UTF_8); FileUtils.readLines(new File(path));<br />這樣作的方法有個問題就是,文件會被保存在內存中,若是文件太大的話,會形成OutOfMemoryError 下面舉個例子,讀取1Gb的文件:
@Test public void givenUsingGuava_whenIteratingAFile_thenWorks() throws IOException { String path = ... Files.readLines(new File(path), Charsets.UTF_8); }剛開始內存使用:
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 128 Mb [main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 116 Mb讀取全部文件後,咱們再來看看內存使用
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 2666 Mb [main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 490 Mb咱們能夠看到。大約2.1Gb的內存被消耗。緣由很簡單,這個方法將文件徹底加載到了內存當中。 經過以上的驗證,咱們能夠清楚的知道。將全部的文件都保存在內存中是很是消耗內存的。 還有就是,咱們一般也不須要把文件都放在內存中來讀。咱們須要的是對文件的循環讀取,須要的功能是讀取——處理——丟棄。咱們要作的就是,依次讀取依次遍歷全部的文件。
如今咱們來看一下解決方法,咱們用到java.util.Scanner 來獲取文件內容,而且依次讀取數據內容: code
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); } // note that Scanner suppresses exceptions if (sc.ioException() != null) { throw sc.ioException(); } } finally { if (inputStream != null) { inputStream.close(); } if (sc != null) { sc.close(); } }這個方法遍歷了文件全部內容,能夠處理每一行的記錄。沒有將內容一直存在內存中:
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 763 Mb [main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 339 Mb</p>
這篇文章就講解了讀取一個大文件的一個不錯的方法。能夠減小一些沒必要要的內存使用htm