如何在Java中逐行讀取文件

本文翻譯自How to read a file line by line in Javahtml

有時咱們想逐行讀取一個文件來處理內容。 一個很好的例子是逐行讀取CSV文件,而後將其用逗號(,)分紅多列。java

在Java中,當您須要逐行讀取文件時,有多種選項可供選擇。git

1.Scanner

Scanner類提供了用Java逐行讀取文件的最簡單方法。 咱們可使用Scanner類打開文件,而後逐行讀取其內容。github

Scanner程序使用定界符模式將其輸入分爲令牌,在本例中爲新行:web

try { 
 
   
    // open file to read
    Scanner scanner = new Scanner(new File("examplefile.txt"));

    // read until end of file (EOF)
    while (scanner.hasNextLine()) { 
 
   
        System.out.println(scanner.nextLine());
    }

    // close the scanner
    scanner.close();
        
} catch (FileNotFoundException ex) { 
 
   
    ex.printStackTrace();
}

若是此掃描程序的輸入中有另外一行而不推動文件讀取位置,則hasNextLine()方法將返回trueshell

要讀取數據並移至下一行,咱們應使用nextLine()方法。 此方法將掃描儀移到當前行以後,並返回當前行的其他部分,但不包括最後的任何行分隔符。 而後將讀取位置設置爲下一行的開頭。api

因爲nextLine()方法繼續在輸入中搜索以尋找行分隔符,所以若是不存在行分隔符,它能夠緩衝全部要搜索的輸入以跳過該行。數組

2. BufferedReader

BufferedReader類提供了一種從字符輸入流中讀取字符,數組和行的有效方法。oracle

顧名思義,它最多可緩衝8MB(或8192KB)的字符,對於大多數用例而言,這足夠大。 若是您正在讀取的文件大於默認緩衝區大小,則能夠自定義默認大小:dom

BufferedReader br = new BufferedReader(new FileReader(" foo.txt"), size);

BufferedReader構造函數接受一個Reader實例(如FileReaderInputStreamReader)做爲字符輸入流源。 這是一個簡單的示例,顯示瞭如何使用它逐行讀取文件:

try { 
 
   
    // create a reader instance
    BufferedReader br = new BufferedReader(new FileReader("examplefile.txt"));

    // read until end of file
    String line;
    while ((line = br.readLine()) != null) { 
 
   
        System.out.println(line);
    }

    // close the reader
    br.close();
        
} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

readLine()方法從文件中讀取一行文本,並返回一個包含該行內容的字符串,但不包括任何行終止字符或null。

注意:null值並不表示字符串爲空。 而是代表已到達文件末尾。

另外,您可使用BufferedReader類中的lines()方法返回行流。 您能夠輕鬆地將此流轉換爲列表或閱讀如下內容:

try { 
 
   
    // create a reader instance
    BufferedReader br = new BufferedReader(new FileReader("examplefile.txt"));

    // list of lines
    List<String> list = new ArrayList<>();

    // convert stream into list
    list = br.lines().collect(Collectors.toList());

    // print all lines
    list.forEach(System.out::println);

    // close the reader
    br.close();
        
} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

3. Java 8 Stream

Java 8 Stream是另外一種逐行讀取文件的方式(儘管更乾淨)。 咱們可使用Files.lines()靜態方法來初始化行流,以下所示:

try { 
 
   
    // initialize lines stream
    Stream<String> stream = Files.lines(Paths.get("examplefile.txt"));

    // read lines
    stream.forEach(System.out::println);

    // close the stream
    stream.close();

} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

4. New I/O API

Java新的I/O API或NIO(java.nio.*包中的類)提供了Files.readAllLines()方法來將文本文件逐行讀取到List <String>中,以下所示:

try { 
 
   
    // read all lines
    List<String> lines = Files.readAllLines(Paths.get("examplefile.txt"));

    // print all lines
    lines.forEach(System.out::println);

} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

5. RandomAccessFile

RandomAccessFile類提供讀寫文件的非阻塞模式。 隨機訪問文件的行爲相似於存儲在文件系統中的大字節數組。

咱們可使用RandomAccessFile以讀取模式打開文件,而後使用其readLine()方法逐行讀取:

try { 
 
   
    // open file in read mode
    RandomAccessFile file = new RandomAccessFile("examplefile.txt", "r");
    // read until end of file
    String line;
    while ((line = file.readLine()) != null) { 
 
   
        System.out.println(line);
    }

    // close the file
    file.close();
        
} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

6. Apache Commons IO

Apache Commons IO庫包含實用程序類,流實現,文件過濾器,文件比較器等。 將如下內容添加到build.gradle文件中,以將庫導入項目中:

implementation 'commons-io:commons-io:2.6'

若是您使用的是Maven,請將如下內容添加到·pom.xml·文件中:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

如今,咱們可使用FileUtils.readLines()(來自Apache Commons IO的靜態方法)將文件中的全部行讀取到List <String>中:

try { 
 
   
    // read all lines of a file
    List<String> lines = FileUtils.readLines(Paths.get("examplefile.txt").toFile(), "UTF-8");

    // process the lines
    for (String line : lines) { 
 
   
        System.out.println(line);
    }

} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

因爲Apache Commons IO一次讀取文件中的全部行,所以對於讀取大文件而言,這可能不是一個好的解決方案。 在上述狀況下,它將繼續阻止for循環執行,直到將全部行添加到lines對象爲止。

7.Okie

Okie是由Square爲Android,Kotlin和Java開發的另外一個開源I/O庫。 它補充了本機java.iojava.nio包,使訪問,保存和處理數據變得更加容易。

要在項目中導入Okie,請將如下內容添加到build.gradle文件中:

implementation 'com.squareup.okio:okio:2.4.0'

若是您使用的是Maven,請將如下內容添加到pom.xml文件中:

<dependency>
    <groupId>com.squareup.okio</groupId>
    <artifactId>okio</artifactId>
    <version>2.4.0</version>
</dependency>

如今,咱們可使用Okio.source()方法打開源流以讀取文件。 返回的Source接口很小,用途有限。 Okie提供了BufferedSource類來用緩衝區包裝源,從而使程序運行更快。

讓咱們舉個例子:

try { 
 
   
    // open a source stream
    Source source = Okio.source(Paths.get("examplefile.txt").toFile());

    // wrap stream with a buffer
    BufferedSource bs = Okio.buffer(source);

    // read until end of file
    String line;
    while ((line = bs.readUtf8Line()) != null) { 
 
   
        System.out.println(line);
    }

    // close the stream
    source.close();

} catch (IOException ex) { 
 
   
    ex.printStackTrace();
}

readUtf8Line()方法讀取數據,直到下一行分隔符– \ n\ r \ n或文件的末尾。 它以字符串形式返回該數據,並在最後省略定界符。 當遇到空行時,該方法將返回一個空字符串。 若是沒有更多的數據可讀取,它將返回null

進一步閱讀

您可能對其餘Java I/O文章感興趣:

上次更新:2020年2月18日
Java

您可能還喜歡…

本文同步分享在 博客「雪域迷影」(CSDN)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索