Cara membaca teks besar file baris demi baris menggunakan Java?

Saya perlu untuk membaca file teks besar sekitar 5-6 GB baris demi baris menggunakan Java.

Bagaimana saya bisa melakukan ini dengan cepat?

Mengomentari pertanyaan (4)

Pola yang umum adalah dengan menggunakan

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

Anda dapat membaca data lebih cepat jika anda menganggap tidak ada pengkodean karakter. misalnya ASCII-7 tapi itu tidak't membuat banyak perbedaan. Hal ini sangat mungkin bahwa apa yang anda lakukan dengan data-data yang akan memakan waktu lebih lama.

EDIT: YANG kurang umum pola penggunaan yang menghindari lingkup line bocor.

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

UPDATE: Di Jawa 8 yang dapat anda lakukan

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

CATATAN: Anda harus menempatkan Streaming di mencoba-dengan-sumber daya blok untuk memastikan #dekat metode ini disebut di atasnya, jika tidak menangani file yang mendasari adalah tidak pernah ditutup sampai GC tidak lama kemudian.

Komentar (33)

Lihat di blog ini:

ukuran buffer dapat ditentukan, atau ukuran default dapat digunakan. Yang default adalah cukup besar untuk sebagian besar tujuan.

// 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();
Komentar (4)

Setelah [tag:jawa-8] keluar (Maret 2014), kau'akan dapat menggunakan aliran:

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

Cetak semua baris dalam file:

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

Berikut adalah sampel dengan penuh kesalahan penanganan dan mendukung charset spesifikasi untuk pra-Jawa 7. Dengan Java 7 anda dapat menggunakan try-dengan-sumber daya sintaks, yang membuat kode cleaner.

Jika anda hanya ingin default charset anda dapat melewatkan InputStream dan menggunakan 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 */ } }
}

Berikut ini adalah Groovy versi, dengan penuh penanganan kesalahan:

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

Di Java 8, anda bisa melakukan:

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

Beberapa catatan: aliran dikembalikan oleh File.garis-garis (tidak seperti kebanyakan sungai) harus ditutup. Untuk alasan yang disebutkan di sini saya menghindari menggunakan forEach(). Aneh code (Iterable<String>) garis::iterator melemparkan Streaming ke Iterable.

Komentar (8)

Apa yang dapat anda lakukan adalah memindai seluruh teks menggunakan Scanner dan pergi melalui teks baris demi baris. Tentu saja anda harus mengimpor berikut:

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
    }
}

Scanner pada dasarnya scan semua teks. Loop while digunakan untuk melintasi melalui seluruh teks.

The .hasNextLine() fungsi boolean yang mengembalikan true jika masih ada lebih banyak baris dalam teks. The .nextLine() fungsi memberikan anda sebuah garis sebagai String yang kemudian dapat anda gunakan dengan cara yang anda inginkan. Mencoba Sistem.keluar.println(line) untuk mencetak teks.

Catatan: .txt adalah jenis file teks.

Komentar (2)

FileReader won't membiarkan anda menentukan encoding, gunakan InputStreamReaderbukan jika anda perlu untuk menentukan itu:

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();
}

Jika anda mengimpor file ini dari Windows, mungkin ANSI encoding (Cp1252), sehingga anda harus menentukan encoding.

Komentar (1)

Di Jawa 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);
}
Komentar (5)

Saya terdokumentasi dan teruji 10 cara yang berbeda untuk membaca file di Jawa dan kemudian berlari mereka terhadap satu sama lain dengan membuat mereka baca di test file dari 1KB 1GB. Berikut ini adalah tercepat 3 membaca file metode untuk membaca 1GB file tes.

Perhatikan bahwa ketika menjalankan tes kinerja saya didn't output apa pun ke konsol karena itu akan benar-benar memperlambat tes. Aku hanya ingin menguji mentah kecepatan membaca.

  1. pulau jawa.nio.file.File.readAllBytes()

Diuji di Java 7, 8, 9. Ini adalah keseluruhan metode tercepat. Membaca 1GB file secara konsisten hanya di bawah 1 detik.

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);
    }
  }
}
  1. pulau jawa.nio.file.File.garis()

Ini telah berhasil diuji di Jawa 8 dan 9, tetapi itu tidak't bekerja di Java 7 karena kurangnya dukungan terhadap ekspresi lambda. Butuh waktu sekitar 3,5 detik untuk membaca di sebuah 1GB file yang meletakkannya di tempat kedua sejauh membaca file yang lebih besar.

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);
      });
    }
  }
}
  1. BufferedReader

Diuji untuk bekerja di Java 7, 8, 9. Ini butuh waktu sekitar 4,5 detik untuk membaca di sebuah 1GB file tes.

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);
      }
    }
  }

Anda dapat menemukan peringkat lengkap untuk semua 10 membaca file metode di sini.

Komentar (3)

Di Java 8, ada juga alternatif untuk menggunakan Files.garis(). Jika anda input sumber isn't file tapi sesuatu yang lebih abstrak seperti Reader atau InputStream, anda dapat stream garis melalui BufferedReader inigaris()` metode.

Misalnya:

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

akan sebut processLine() untuk setiap input line dibaca oleh BufferedReader.

Komentar (0)

Untuk Membaca file dengan jawa 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 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();
        }
        }
    }
Komentar (0)

Anda dapat menggunakan Scanner kelas

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

Anda perlu menggunakan readLine() metode class BufferedReader. Membuat objek baru dari kelas itu dan beroperasi metode ini pada-nya dan menyimpannya ke sebuah string.

BufferReader Javadoc

Komentar (1)

Jawa-9 :

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

Cara yang jelas untuk mencapai hal ini,

Misalnya:

Jika anda memiliki dataFile.txt pada direktori anda saat ini

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();
    }
}

Output seperti di bawah ini,

Komentar (2)
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");
}

Ia bekerja untuk saya. Berharap Ini akan membantu anda terlalu.

Komentar (0)

Saya biasanya melakukan pembacaan rutin sederhana:

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) {
        }
    }
}
Komentar (0)

Anda dapat menggunakan sungai untuk melakukannya lebih tepatnya:

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

dengan menggunakan org.apache.commons.io paket memberikan kinerja yang lebih terutama dalam warisan kode yang menggunakan Java 6 dan di bawah. Java7 telah baik API dengan sedikit pengecualian penanganan dan metode yang lebih berguna

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

maven



    commons-io
    commons-io
    2.6
Komentar (0)

Anda juga dapat menggunakan apache commons io:

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