Làm cách nào tôi có thể đọc một dòng tệp văn bản lớn theo từng dòng bằng Java?


847

Tôi cần đọc một tệp văn bản lớn khoảng 5-6 GB theo từng dòng bằng Java.

Làm thế nào tôi có thể làm điều này một cách nhanh chóng?


69
@kamaci et. al. Câu hỏi này không nên được đánh dấu là một bản sao. "Đọc nhanh dòng cuối cùng" không phải là một cách thay thế, và nó gây tranh cãi liệu "Cách nhanh nhất để đọc từng dòng tệp văn bản" là. Cách nhanh nhất để làm một cái gì đó không nhất thiết là cách phổ biến. Hơn nữa, các câu trả lời dưới đây bao gồm mã, sự thay thế phù hợp nhất mà bạn liệt kê không có. Câu hỏi này rất hữu ích. Nó hiện là kết quả tìm kiếm hàng đầu của google cho "java đọc từng dòng tệp". Cuối cùng, việc đưa ra để tràn vào ngăn xếp và thấy rằng cứ 1 trong 2 câu hỏi được gắn cờ để xử lý.
Patrick Cullen

5
Dưới đây là so sánh tốc độ cho sáu triển khai có thể.
Serg M Ten

4
Sự kiện mặc dù tôi đã đọc các bình luận lập luận rằng chính sách chặt chẽ của SO hút, SO vẫn tồn tại trong đó. Đó là một quan điểm nhà phát triển có đầu óc hẹp hòi muốn tránh sự dư thừa bằng mọi giá! Cứ để tự nhiên! Kem sẽ nổi lên trên cùng và sh * t sẽ chìm xuống đáy chỉ tốt thôi. Mặc dù một câu hỏi có thể đã được hỏi trước đó (câu hỏi nào không ??), điều đó không có nghĩa là một câu hỏi mới có thể không thể diễn đạt tốt hơn, nhận được câu trả lời tốt hơn, xếp hạng cao hơn trong công cụ tìm kiếm, v.v. câu hỏi hiện được 'bảo vệ' ....
Stijn de Witt

3
Thật đáng kinh ngạc khi các câu hỏi được đánh dấu là trùng lặp bằng cách chỉ đọc tiêu đề.
Lu-ca

Câu trả lời:


1063

Một mô hình phổ biến là sử dụng

try (BufferedReader br = new BufferedReader(new FileReader(file))) {
    String line;
    while ((line = br.readLine()) != null) {
       // process the line.
    }
}

Bạn có thể đọc dữ liệu nhanh hơn nếu bạn cho rằng không có mã hóa ký tự. ví dụ ASCII-7 nhưng nó sẽ không tạo ra nhiều khác biệt. Rất có khả năng những gì bạn làm với dữ liệu sẽ mất nhiều thời gian hơn.

EDIT: Một mô hình ít phổ biến hơn để sử dụng để tránh phạm vi linerò rỉ.

try(BufferedReader br = new BufferedReader(new FileReader(file))) {
    for(String line; (line = br.readLine()) != null; ) {
        // process the line.
    }
    // line is not visible here.
}

CẬP NHẬT: Trong Java 8 bạn có thể làm

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
        stream.forEach(System.out::println);
}

LƯU Ý: Bạn phải đặt Luồng trong khối thử tài nguyên để đảm bảo phương thức #close được gọi trên đó, nếu không, phần xử lý tệp bên dưới sẽ không bao giờ bị đóng cho đến khi GC thực hiện sau đó.


6
Mô hình này trông như thế nào với xử lý ngoại lệ thích hợp? Tôi lưu ý rằng br.close () ném IOException, điều này có vẻ đáng ngạc nhiên - điều gì có thể xảy ra khi đóng một tệp được mở để đọc, dù sao? Trình xây dựng của FileReader có thể ném ngoại lệ FileNotFound.
MikeB

3
Nếu tôi có một tệp 200 MB và nó có thể đọc với tốc độ 90 MB / giây thì tôi hy vọng nó sẽ mất ~ 3 giây? Của tôi dường như mất vài phút, với cách đọc "chậm" này. Tôi đang sử dụng ổ SSD nên tốc độ đọc không phải là vấn đề?
Jiew Meng

4
@JiewMeng SO Tôi sẽ nghi ngờ điều gì đó khác mà bạn đang làm là mất thời gian. Bạn có thể thử chỉ đọc các dòng của tập tin và không có gì khác.
Peter Lawrey

44
Tại sao không for(String line = br.readLine(); line != null; line = br.readLine())Btw, trong Java 8 bạn có thể làm try( Stream<String> lines = Files.lines(...) ){ for( String line : (Iterable<String>) lines::iterator ) { ... } }Điều đó thật khó để không ghét.
Alexanderr Dubinsky

26
@AleksandrDubinsky Vấn đề tôi gặp phải khi đóng trong Java 8 là nó rất dễ làm cho mã trở nên phức tạp hơn để đọc (cũng như chậm hơn) Tôi có thể thấy rất nhiều nhà phát triển lạm dụng nó vì nó "tuyệt".
Peter Lawrey

155

Nhìn vào blog này:

Kích thước bộ đệm có thể được chỉ định hoặc kích thước mặc định có thể được sử dụng. Mặc định là đủ lớn cho hầu hết các mục đích.

// Open the file
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

String strLine;

//Read File Line By Line
while ((strLine = br.readLine()) != null)   {
  // Print the content on the console
  System.out.println (strLine);
}

//Close the input stream
fstream.close();

6
Tệp của tôi là 1,5 Gig và không thể đọc tệp bằng câu trả lời của bạn!
Aboozar Rajabi

3
@AboozarRajabi Tất nhiên là có thể. Mã này có thể đọc bất kỳ tập tin văn bản.
Hầu tước Lorne

10
Downvote cho liên kết chất lượng kém. Có một điều hoàn toàn vô nghĩa DataInputStream, và luồng sai được đóng lại. Không có gì sai với Hướng dẫn Java và không cần trích dẫn rác Internet của bên thứ ba tùy tiện như thế này.
Hầu tước Lorne

1
Tôi sẽ bỏ các bình luận, bạn có 4 dòng bình luận dự phòng 100% cho 6 dòng mã.
Trâu

97

Khi Java 8 ra mắt (tháng 3 năm 2014), bạn sẽ có thể sử dụng các luồng:

try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {
  lines.forEachOrdered(line -> process(line));
}

In tất cả các dòng trong tệp:

try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) {
  lines.forEachOrdered(System.out::println);
}

1
Sử dụng StandardCharsets.UTF_8, sử dụng Stream<String>cho sự thống nhất và tránh sử dụng forEach()và đặc biệt forEachOrdered()trừ khi có lý do.
Alexanderr Dubinsky

2
Tại sao nên tránh forEach ()? Nó có tồi không?
steventrouble

Nếu tôi cho chúng tôi thay vì forEachOrdered, các dòng có thể được in không theo thứ tự, phải không?
msayag

2
@steventrouble Hãy xem: stackoverflow.com/questions/16635398/ Khăn Thật không tệ nếu bạn chuyển một tham chiếu hàm ngắn như thế forEach(this::process), nhưng sẽ trở nên xấu xí nếu bạn viết các khối mã như lambdas bên trong forEach().
Alexanderr Dubinsky 8/03/2015

2
@msayag, Bạn nói đúng, bạn cần forEachOrderedđể thực hiện theo thứ tự. Xin lưu ý rằng bạn sẽ không thể song song hóa luồng trong trường hợp đó, mặc dù tôi đã thấy rằng song song hóa không bật trừ khi tệp có hàng ngàn dòng.
Alexanderr Dubinsky 8/03/2015

38

Dưới đây là một mẫu với xử lý lỗi đầy đủ và đặc tả bộ ký tự hỗ trợ cho tiền Java 7. Với Java 7, bạn có thể sử dụng cú pháp try-with-resource, giúp mã sạch hơn.

Nếu bạn chỉ muốn bộ ký tự mặc định, bạn có thể bỏ qua InputStream và sử dụng FileReader.

InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
BufferedReader br = null; // buffered for readLine()
try {
    String s;
    ins = new FileInputStream("textfile.txt");
    r = new InputStreamReader(ins, "UTF-8"); // leave charset out for default
    br = new BufferedReader(r);
    while ((s = br.readLine()) != null) {
        System.out.println(s);
    }
}
catch (Exception e)
{
    System.err.println(e.getMessage()); // handle exception
}
finally {
    if (br != null) { try { br.close(); } catch(Throwable t) { /* ensure close happens */ } }
    if (r != null) { try { r.close(); } catch(Throwable t) { /* ensure close happens */ } }
    if (ins != null) { try { ins.close(); } catch(Throwable t) { /* ensure close happens */ } }
}

Đây là phiên bản Groovy, với xử lý lỗi đầy đủ:

File f = new File("textfile.txt");
f.withReader("UTF-8") { br ->
    br.eachLine { line ->
        println line;
    }
}

1
Điều gì ByteArrayInputStreamđược cung cấp bởi một chuỗi chữ có liên quan đến việc đọc một tệp văn bản lớn?
Hầu tước Lorne

hoàn toàn vô dụng đóng cửa. Không có lý do để đóng mọi luồng. Nếu bạn đóng bất kỳ luồng nào trong số đó, bạn sẽ tự động đóng tất cả các luồng khác ...
Enerccio

21

Trong Java 8, bạn có thể làm:

try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8))
{
    for (String line : (Iterable<String>) lines::iterator)
    {
        ;
    }
}

Một số lưu ý: Luồng được trả về bởi Files.lines(không giống như hầu hết các luồng) cần phải được đóng lại. Vì những lý do được đề cập ở đây tôi tránh sử dụng forEach(). Mã lạ (Iterable<String>) lines::iteratorđưa một luồng đến một vòng lặp.


Bằng cách không thực hiện Iterablemã này chắc chắn là xấu mặc dù hữu ích. Nó cần một diễn viên (tức là (Iterable<String>)) để làm việc.
Stephan

Làm thế nào tôi có thể bỏ qua dòng đầu tiên với phương pháp này?
qed

2
@qedfor(String line : (Iterable<String>) lines.skip(1)::iterator)
Dubinsky

1
Nếu bạn không có ý định thực sự sử dụng Streamcác tính năng, sử dụng Files.newBufferedReaderthay vì Files.linesvà liên tục gọi readLine()cho đến khi nullthay vì sử dụng các cấu trúc như (Iterable<String>) lines::iteratorcó vẻ đơn giản hơn nhiều
Holger

Tại sao bạn sử dụng :: in lines :: iterator? Chỉ sử dụng mà tôi biết cho :: là đóng gói tên phương thức vào hàm lambda. Trong tham số vòng lặp sau: nên biến trong khi bạn nhận được một số phương thức lambda bằng cách sử dụng ::
Trismegistos

19

Những gì bạn có thể làm là quét toàn bộ văn bản bằng Máy quét và đi qua từng dòng văn bản. Tất nhiên bạn nên nhập như sau:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public static void readText throws FileNotFoundException {
    Scanner scan = new Scanner(new File("samplefilename.txt"));
    while(scan.hasNextLine()){
        String line = scan.nextLine();
        //Here you can manipulate the string the way you want
    }
}

Máy quét về cơ bản quét tất cả các văn bản. Vòng lặp while được sử dụng để duyệt qua toàn bộ văn bản.

Các .hasNextLine()chức năng là một boolean mà trả về true nếu vẫn còn nhiều dòng trong văn bản. Các .nextLine()chức năng cung cấp cho bạn toàn bộ một dòng như là một String mà sau đó bạn có thể sử dụng theo cách bạn muốn. Cố gắng System.out.println(line)in văn bản.

Lưu ý bên: .txt là văn bản loại tệp.


Không nên khai báo phương thức thay vì điều này: ỉpublic static void readText ném FileNotFoundException () {ượng Giống như: ọpublic static void readText () ném FileNotFoundException {
ỉm

Điều này chậm hơn đáng kể so với BufferedReader.readLine(), và ông đã yêu cầu phương pháp thực hiện tốt nhất.
Hầu tước Lorne

18

FileReader sẽ không cho phép bạn chỉ định mã hóa, InputStreamReaderthay vào đó hãy sử dụng nếu bạn cần chỉ định nó:

try {
    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"));         

    String line;
    while ((line = br.readLine()) != null) {
        // process the line.
    }
    br.close();

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

Nếu bạn đã nhập tệp này từ Windows, nó có thể có mã hóa ANSI (Cp1252), vì vậy bạn phải chỉ định mã hóa.


17

Tôi đã ghi lại và thử nghiệm 10 cách khác nhau để đọc một tệp trong Java và sau đó chạy chúng với nhau bằng cách làm cho chúng đọc trong các tệp thử nghiệm từ 1KB đến 1GB. Dưới đây là 3 phương pháp đọc tệp nhanh nhất để đọc tệp kiểm tra 1GB.

Lưu ý rằng khi chạy các bài kiểm tra hiệu năng, tôi không xuất bất kỳ thứ gì lên bàn điều khiển vì điều đó thực sự sẽ làm chậm bài kiểm tra. Tôi chỉ muốn kiểm tra tốc độ đọc thô.

1) java.nio.file.Files.read ALLBytes ()

Đã thử nghiệm trong Java 7, 8, 9. Đây là phương pháp nhanh nhất. Đọc tệp 1GB liên tục chỉ dưới 1 giây.

import java.io..File;
import java.io.IOException;
import java.nio.file.Files;

public class ReadFile_Files_ReadAllBytes {
  public static void main(String [] pArgs) throws IOException {
    String fileName = "c:\\temp\\sample-1GB.txt";
    File file = new File(fileName);

    byte [] fileBytes = Files.readAllBytes(file.toPath());
    char singleChar;
    for(byte b : fileBytes) {
      singleChar = (char) b;
      System.out.print(singleChar);
    }
  }
}

2) java.nio.file.Files.lines ()

Điều này đã được thử nghiệm thành công trong Java 8 và 9 nhưng nó sẽ không hoạt động trong Java 7 vì thiếu sự hỗ trợ cho các biểu thức lambda. Mất khoảng 3,5 giây để đọc trong tệp 1GB, đặt nó ở vị trí thứ hai xa như đọc các tệp lớn hơn.

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;

public class ReadFile_Files_Lines {
  public static void main(String[] pArgs) throws IOException {
    String fileName = "c:\\temp\\sample-1GB.txt";
    File file = new File(fileName);

    try (Stream linesStream = Files.lines(file.toPath())) {
      linesStream.forEach(line -> {
        System.out.println(line);
      });
    }
  }
}

3) Bộ đệm

Đã thử nghiệm để hoạt động trong Java 7, 8, 9. Điều này mất khoảng 4,5 giây để đọc trong tệp thử nghiệm 1GB.

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile_BufferedReader_ReadLine {
  public static void main(String [] args) throws IOException {
    String fileName = "c:\\temp\\sample-1GB.txt";
    FileReader fileReader = new FileReader(fileName);

    try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
      String line;
      while((line = bufferedReader.readLine()) != null) {
        System.out.println(line);
      }
    }
  }

Bạn có thể tìm thấy bảng xếp hạng hoàn chỉnh cho tất cả 10 phương pháp đọc tệp tại đây .


1
Hướng dẫn của bạn thật tuyệt vời :)
Faisal Julaidan

Bạn chủ yếu là thời gian System.out.print/println()ở đây; bạn cũng cho rằng tập tin sẽ vừa với bộ nhớ trong hai trường hợp đầu tiên của bạn.
Hầu tước Lorne

Đủ công bằng. Có lẽ tôi đã có thể làm cho những giả định đó rõ ràng hơn trong câu trả lời của mình.
gomisha

16

Trong Java 7:

String folderPath = "C:/folderOfMyFile";
Path path = Paths.get(folderPath, "myFileName.csv"); //or any text file eg.: txt, bat, etc
Charset charset = Charset.forName("UTF-8");

try (BufferedReader reader = Files.newBufferedReader(path , charset)) {
  while ((line = reader.readLine()) != null ) {
    //separate all csv fields into string array
    String[] lineVariables = line.split(","); 
  }
} catch (IOException e) {
    System.err.println(e);
}

9
cảnh giác sử dụng line.split theo cách này sẽ KHÔNG phân tích đúng nếu một trường có dấu phẩy và nó được bao quanh bởi dấu ngoặc kép. Sự phân tách này sẽ bỏ qua điều đó và chỉ tách trường trong các đoạn bằng cách sử dụng dấu phẩy bên trong. HTH, Marcelo.
Marcelo Finki

CSV: Tệp Giá trị được phân tách bằng dấu phẩy, do đó bạn không nên sử dụng dấu phẩy trong trường csv, trừ khi bạn muốn thêm một trường khác. Vì vậy, sử dụng phân tách cho mã thông báo dấu phẩy trong java khi phân tích tệp CSV là hoàn toàn tốt và đúng
Diego Duarte

7
Diego, điều này không chính xác. Tiêu chuẩn CSV duy nhất (RFC 4180) nói cụ thể "Các trường chứa ngắt dòng (CRLF), dấu ngoặc kép và dấu phẩy phải được đặt trong dấu ngoặc kép".
serg.nechaev

2
Sử dụng StandardCharsets.UTF_8để tránh ngoại lệ được kiểm tra trongCharset.forName("UTF-8")
Alexanderr Dubinsky 8/03/2015

2
Cảm ơn bạn "Diego Duarte" cho nhận xét của bạn; tôi phải nói rằng tôi đồng ý với những gì "serg.nechaev" trả lời. Tôi thấy dấu phẩy được nhúng trong tệp csv 'mọi lúc'. Mọi người mong đợi rằng điều này sẽ được chấp nhận. với tất cả sự kính trọng. cũng rất cảm ơn "serg.nechaev". IMHO bạn đúng. Chúc mừng tất cả mọi người.
Marcelo Finki

13

Trong Java 8, cũng có một cách khác để sử dụng Files.lines(). Nếu nguồn đầu vào của bạn không phải là một tệp mà là một thứ gì đó trừu tượng hơn như một Readerhoặc một InputStream, bạn có thể truyền phát các dòng thông qua phương thức BufferedReaders lines().

Ví dụ:

try (BufferedReader reader = new BufferedReader(...)) {
  reader.lines().forEach(line -> processLine(line));
}

sẽ gọi processLine()cho mỗi dòng đầu vào được đọc bởi BufferedReader.


10

Để đọc một tệp với Java 8

package com.java.java8;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

/**
 * The Class ReadLargeFile.
 *
 * @author Ankit Sood Apr 20, 2017
 */
public class ReadLargeFile {

    /**
     * The main method.
     *
     * @param args
     *            the arguments
     */
    public static void main(String[] args) {
        try {
            Stream<String> stream = Files.lines(Paths.get("C:\\Users\\System\\Desktop\\demoData.txt"));
            stream.forEach(System.out::println);
        }
        catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

9

Bạn có thể sử dụng lớp Scanner

Scanner sc=new Scanner(file);
sc.nextLine();

2
@Tim 'Bom khủng khiếp' không phải là một thuật ngữ tôi nhận ra trong CS. Chính xác ý của bạn là gì?
Hầu tước Lorne

Bog xuống, thực hiện rất chậm, rất có thể sụp đổ. Tôi có lẽ nên tránh các thành ngữ trên trang web này;)
Tim

4
@Tim Tại sao nó lại làm như vậy?
xehpuk

2
Sử dụng Scannerlà tốt, nhưng câu trả lời này không bao gồm mã đầy đủ để sử dụng nó đúng cách.
Alexanderr Dubinsky 8/03/2015

5
@Tim Mã này sẽ không 'đánh bom khủng khiếp' cũng không 'sa lầy' cũng không 'thực thi rất chậm' cũng như 'rất có thể là sự cố'. Như một vấn đề thực tế như được viết, nó sẽ chỉ đọc một dòng, gần như ngay lập tức. Bạn có thể đọc megabyte mỗi giây theo cách này, mặc dù BufferedReader.readLine()chắc chắn là nhanh gấp nhiều lần. Nếu bạn nghĩ khác xin vui lòng cung cấp lý do của bạn.
Hầu tước Lorne

7

Bạn cần sử dụng readLine()phương pháp trong class BufferedReader. Tạo một đối tượng mới từ lớp đó và vận hành phương thức này trên anh ta và lưu nó vào một chuỗi.

Bộ đệm Javadoc


Có vẻ như liên kết đến BufferReaderAPI đã bị hỏng
Sandeep

6

Cách rõ ràng để đạt được điều này,

Ví dụ:

Nếu bạn có dataFile.txttrong thư mục hiện tại của bạn

import java.io.*;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class readByLine
{
    public readByLine() throws FileNotFoundException
    {
        Scanner linReader = new Scanner(new File("dataFile.txt"));

        while (linReader.hasNext())
        {
            String line = linReader.nextLine();
            System.out.println(line);
        }
        linReader.close();

    }

    public static void main(String args[])  throws FileNotFoundException
    {
        new readByLine();
    }
}

Đầu ra như dưới đây, nhập mô tả hình ảnh ở đây


Tại sao nó rõ ràng hơn? Và đừng đăng hình ảnh của văn bản ở đây. Đăng văn bản.
Hầu tước Lorne

Bạn đăng một bức ảnh. Đó là một hình ảnh của văn bản. Bạn có thể đã cắt và dán văn bản trực tiếp vào trang này. Không ai nói bất cứ điều gì về việc đăng chương trình. Đăng hình ảnh của văn bản là một sự lãng phí thời gian của bạn, điều mà tôi không quan tâm, và băng thông rộng, mà tôi làm.
Hầu tước Lorne

6

Java 9:

try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
    stream.forEach(System.out::println);
}

2
Tôi nghĩ bạn phảiSystem.getProperty("os.name").equals("Linux")
SpringLearner

5
Đừng so sánh chuỗi với ==!
JonasCz - Tái lập Monica

6
Đây là ví dụ Java 8 chuẩn, như đã được đăng bởi những người khác. Tại sao bạn cho rằng đây là Java Java-9 nên?
Holger

Bộ nhớ @Holger ánh xạ tập tin mà anh quên đề cập có thể là?
Eugene

để xử lý từng dòng một, bạn có thể thử (Stream <String> stream = Files.lines (Paths.get (inputFile))) {stream.forEach ((line) -> {System.out.println (line);} ); }
thanos.a

3
BufferedReader br;
FileInputStream fin;
try {
    fin = new FileInputStream(fileName);
    br = new BufferedReader(new InputStreamReader(fin));

    /*Path pathToFile = Paths.get(fileName);
    br = Files.newBufferedReader(pathToFile,StandardCharsets.US_ASCII);*/

    String line = br.readLine();
    while (line != null) {
        String[] attributes = line.split(",");
        Movie movie = createMovie(attributes);
        movies.add(movie);
        line = br.readLine();
    }
    fin.close();
    br.close();
} catch (FileNotFoundException e) {
    System.out.println("Your Message");
} catch (IOException e) {
    System.out.println("Your Message");
}

Nó làm việc cho tôi. Hy vọng nó sẽ giúp bạn quá.


3

Bạn có thể sử dụng các luồng để làm điều đó chính xác hơn:

Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);

2
Tôi đồng ý rằng nó thực sự tốt Ái chà, mọi người không thích nó vì lựa chọn StringBuffer lạ (StringBuilder thường được ưa thích hơn, mặc dù nó có thể chỉ là một tên xấu cho biến). Cũng bởi vì nó đã được đề cập ở trên.
Andrii Rubtsov

2

Tôi thường làm các thói quen đọc đơn giản:

void readResource(InputStream source) throws IOException {
    BufferedReader stream = null;
    try {
        stream = new BufferedReader(new InputStreamReader(source));
        while (true) {
            String line = stream.readLine();
            if(line == null) {
                break;
            }
            //process line
            System.out.println(line)
        }
    } finally {
        closeQuiet(stream);
    }
}

static void closeQuiet(Closeable closeable) {
    if (closeable != null) {
        try {
            closeable.close();
        } catch (IOException ignore) {
        }
    }
}

0

Bạn có thể sử dụng mã này:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadTextFile {

    public static void main(String[] args) throws IOException {

        try {

            File f = new File("src/com/data.txt");

            BufferedReader b = new BufferedReader(new FileReader(f));

            String readLine = "";

            System.out.println("Reading file using Buffered Reader");

            while ((readLine = b.readLine()) != null) {
                System.out.println(readLine);
            }

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

    }

}

Một lời giải thích sẽ theo thứ tự.
Peter Mortensen

0

Bằng cách sử dụng gói org.apache.commons.io , nó mang lại hiệu năng cao hơn, đặc biệt là trong mã kế thừa sử dụng Java 6 trở xuống.

Java 7 có API tốt hơn với ít xử lý ngoại lệ hơn và các phương thức hữu ích hơn:

LineIterator lineIterator = null;
try {
    lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256"); // The second parameter is optionnal
    while (lineIterator.hasNext()) {
        String currentLine = lineIterator.next();
        // Some operation
    }
}
finally {
    LineIterator.closeQuietly(lineIterator);
}

Maven

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

0

Bạn cũng có thể sử dụng Apache Commons IO :

File file = new File("/home/user/file.txt");
try {
    List<String> lines = FileUtils.readLines(file);
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

3
FileUtils.readLines(file)là một phương pháp không dùng nữa. Ngoài ra, phương thức gọi IOUtils.readLines, sử dụng BufferedReader và ArrayList. Đây không phải là một phương pháp theo từng dòng và chắc chắn không phải là một phương pháp thực tế để đọc vài GB.
vallismortis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.