JAVA—讀高效讀取大文件

概述

這篇文章將描述怎樣在JAVA中高效的讀取一個大文件html

內存中讀取

咱們通常經常使用的方法是在內存中讀取文件。—包括 Guava 和 Apache Commons IO 都提供了一個簡便的方法來操做:java

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

這是會發生問題的,咱們將全部的文件都保存在了內存中。要是文件過大,就會出現 OutOfMemoryError ;ui

例如,讀取1個1GB的文件code

@Test
public void givenUsingGuava_whenIteratingAFile_thenWorks() throws IOException {
    String path = ...
    Files.readLines(new File(path), Charsets.UTF_8);
}

內存會被耗盡htm

[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 128 Mb
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 116 Mbip

在咱們讀取完文件操做後。咱們能夠看到內存:內存

[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Total Memory: 2666 Mb
[main] INFO org.baeldung.java.CoreJavaIoUnitTest - Free Memory: 490 Mb開發

這意味着。有2.1GB的內存被使用,緣由很簡單,就是把全部文件都裝入了內存input

但一般。咱們並不須要一次性加載內存中的全部文件。咱們僅僅須要遍歷文件。作一些操做。而後丟棄。因此,咱們如今要作的就是不把文件徹底加入到內存中依次遍歷文件。it

經過流來操做

咱們來看看這個方法。咱們將經過 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);
    }
    // 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: 605 Mb

Apache Commons IO 的文件流

上面的那個操做也能夠經過 Commons IO 來實現每一行的遍歷

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

一樣,也是不在內存中加載所有文件。少許的內存消耗:

[main] INFO o.b.java.CoreJavaIoIntegrationTest - Total Memory: 752 Mb
[main] INFO o.b.java.CoreJavaIoIntegrationTest - Free Memory: 564 Mb

5.結束

好了,文章到此結束,在咱們平常的開發中,在遇到讀取大文件就能夠參照以上的方法了。

相關文章
相關標籤/搜索