Java 大文件讀取

1. 簡介

這篇文章主要是講解展現,在Java中如何高效的讀取大文件中的數據。html

2. 內存裏讀取

通常狀況下,咱們都是在內存中讀取文件——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的內存被消耗。緣由很簡單,這個方法將文件徹底加載到了內存當中。 經過以上的驗證,咱們能夠清楚的知道。將全部的文件都保存在內存中是很是消耗內存的。 還有就是,咱們一般也不須要把文件都放在內存中來讀。咱們須要的是對文件的循環讀取,須要的功能是讀取——處理——丟棄。咱們要作的就是,依次讀取依次遍歷全部的文件。

3. 經過流來讀取文件

如今咱們來看一下解決方法,咱們用到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>

4. 結束語

這篇文章就講解了讀取一個大文件的一個不錯的方法。能夠減小一些沒必要要的內存使用htm

相關文章
相關標籤/搜索