it-swarm.com.de

Wie liest man eine große Textdatei zeilenweise mit Java?

Ich muss zeilenweise eine große Textdatei von 5-6 GB mit Java lesen.

Wie kann ich das schnell machen? 

746
manoj singh

Ein übliches Muster ist zu verwenden

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

Sie können die Daten schneller lesen, wenn Sie davon ausgehen, dass keine Zeichencodierung vorliegt. z.B. ASCII-7 macht aber keinen großen Unterschied. Es ist sehr wahrscheinlich, dass das, was Sie mit den Daten machen, viel länger dauern wird.

BEARBEITEN: Ein weniger übliches Muster, das den Umfang von line undicht macht.

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

UPDATE: In Java 8 ist das möglich

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

HINWEIS: Sie müssen den Stream in einem try-with-resource -Block platzieren, um sicherzustellen, dass die #close-Methode für ihn aufgerufen wird. Andernfalls wird der zugrunde liegende Dateihandle nie geschlossen, bis GC dies später ausführt.

953
Peter Lawrey

Schau dir diesen Blog an:

Die Puffergröße kann angegeben werden oder Die Standardgröße kann verwendet werden. Das Die Standardeinstellung ist groß genug für die meisten Zwecke.

// 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();
133
Naveed

Sobald Java-8 out ist (März 2014), können Sie Streams verwenden:

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

Alle Zeilen in der Datei drucken:

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

Hier ist ein Beispiel mit vollständiger Fehlerbehandlung und Unterstützung der Zeichensatzspezifikation für Pre-Java 7. Mit Java 7 können Sie die try-with-resources-Syntax verwenden, die den Code sauberer macht.

Wenn Sie nur den Standardzeichensatz wünschen, können Sie den InputStream überspringen und FileReader verwenden.

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

Hier ist die Groovy-Version mit vollständiger Fehlerbehandlung:

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

In Java 8 können Sie Folgendes tun:

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

Einige Hinweise: Der von Files.lines (im Gegensatz zu den meisten Streams) zurückgegebene Stream muss geschlossen werden. Aus den Gründen hier erwähnt vermeide ich die Verwendung von forEach(). Der seltsame Code (Iterable<String>) lines::iterator wandelt einen Stream in eine Iterable um.

21

Sie können den gesamten Text mit dem Scanner scannen und den Text Zeile für Zeile durchgehen. __ Natürlich sollten Sie Folgendes importieren:

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

Der Scanner scannt grundsätzlich den gesamten Text. Die while-Schleife wird verwendet, um den gesamten Text zu durchlaufen.

Die Funktion .hasNextLine() ist ein boolescher Wert, der true zurückgibt, wenn der Text noch mehr Zeilen enthält. Die Funktion .nextLine() gibt Ihnen eine gesamte Zeile als String, die Sie dann wie gewünscht verwenden können. Versuchen Sie System.out.println(line), um den Text zu drucken.

Anmerkung: .txt ist der Dateityptext.

19
iskandarchacra

FileReader lässt Sie die Kodierung nicht angeben. Verwenden Sie InputStreamReaderinstead, wenn Sie sie angeben müssen:

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

Wenn Sie diese Datei aus Windows importiert haben, verfügt sie möglicherweise über eine ANSI-Codierung (Cp1252). Daher müssen Sie die Codierung angeben. 

17
live-love

In 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);
}
15
Diego Duarte

Ich dokumentierte und testete 10 verschiedene Arten, eine Datei in Java zu lesen und führte sie dann gegeneinander aus, indem sie in Testdateien von 1 KB bis 1 GB eingelesen wurden. Hier sind die schnellsten 3 Datei-Lesemethoden zum Lesen einer 1 GB-Testdatei.

Beachten Sie, dass ich beim Ausführen der Leistungstests nichts an die Konsole ausgegeben habe, da dies den Test wirklich verlangsamen würde. Ich wollte nur die rohe Lesegeschwindigkeit testen.

1) Java.nio.file.Files.readAllBytes ()

Getestet in Java 7, 8, 9. Dies war insgesamt die schnellste Methode. Das Lesen einer 1 GB-Datei dauerte konstant knapp 1 Sekunde.

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

Dies wurde in Java 8 und 9 erfolgreich getestet, funktioniert jedoch in Java 7 nicht, da keine Lambda-Ausdrücke unterstützt werden. Es dauerte etwa 3,5 Sekunden, um eine 1 GB-Datei einzulesen, was den zweiten Platz beim Lesen größerer Dateien einnimmt.

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) BufferedReader

Getestet, um in Java 7, 8, 9 zu arbeiten. Das Einlesen einer 1 GB-Testdatei dauerte etwa 4,5 Sekunden.

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

Sie finden die vollständigen Rankings für alle 10 Methoden zum Lesen von Dateien hier .

11
gomisha

Zum Lesen der Datei mit 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();
        }
        }
    }
10
Ankit Sood

Sie können die Scanner-Klasse verwenden

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

In Java 8 gibt es auch eine Alternative zur Verwendung von Files.lines() . Wenn Ihre Eingabequelle keine Datei ist, sondern etwas abstrakteres wie eine Reader oder eine InputStream, können Sie die Zeilen mit der Methode BufferedReaders lines()stream.

Zum Beispiel:

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

ruft processLine() für jede von der BufferedReader gelesene Eingabezeile auf.

8

Sie müssen die readLine()-Methode in class BufferedReader..__ verwenden. Erstellen Sie ein neues Objekt aus dieser Klasse und verwenden Sie diese Methode für ihn, und speichern Sie es in einer Zeichenfolge.

BufferReader Javadoc

7
Master C

Java-9:

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

Der klare Weg, dies zu erreichen,

Zum Beispiel:

Wenn Sie dataFile.txt in Ihrem aktuellen Verzeichnis haben

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

Die Ausgabe wie folgt:  enter image description here

5
Rajamohan S
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");
}

Für mich geht das. Hoffe es wird dir auch helfen.

3
Dipendra Ghatal

Normalerweise mache ich die Lese-Routine unkompliziert: 

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) {
        }
    }
}
2

durch die Verwendung vonorg.Apache.commons.iopackage wurde die Leistung insbesondere in älterem Code verbessert, der Java 6 und darunter verwendet.
Java7 hat eine bessere API mit weniger Ausnahmen Und mehr nützliche Methoden 

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 

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

Sie können Streams verwenden, um es genauer zu machen:

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

Sie können auch Apache commons io verwenden:

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

Sie können diesen Code verwenden:

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

    }

}
0
Usman Yaqoob