Pregunta ¿Cómo leer un archivo de texto grande línea por línea usando Java?


Necesito leer un archivo de texto grande de alrededor de 5-6 GB línea por línea usando Java.

¿Cómo puedo hacer esto rápidamente?


681
2018-05-03 10:53


origen


Respuestas:


Un patrón común es usar

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

Puede leer los datos más rápido si supone que no hay codificación de caracteres. p.ej. ASCII-7 pero no hará mucha diferencia. Es muy probable que lo que haga con los datos tarde mucho más.

EDITAR: Un patrón de uso menos común que evita el alcance de line goteando.

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

ACTUALIZACIÓN: en Java 8 puedes hacer

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

NOTA: Debe colocar Stream en un bloque try-with-resource para asegurarse de que se llame al método #close, de lo contrario, el manejador de archivo subyacente nunca se cierra hasta que GC lo haga mucho más tarde.


860
2018-05-03 11:07



Mira este blog:

El tamaño del buffer puede ser especificado, o   el tamaño predeterminado puede ser utilizado. los   el valor predeterminado es lo suficientemente grande para la mayoría   propósitos.

// 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
br.close();

121
2018-05-03 10:57



Una vez  está fuera (marzo de 2014) podrá usar transmisiones:

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

Imprimir todas las líneas en el archivo:

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

78
2017-07-25 18:58



Aquí hay una muestra con manejo completo de errores y especificación de charset de soporte para pre-Java 7. Con Java 7 puede usar la sintaxis try-with-resources, que hace que el código sea más limpio.

Si solo desea el juego de caracteres predeterminado, puede omitir el InputStream y usar 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 */ } }
}

Aquí está la versión de Groovy, con manejo completo de errores:

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

34
2018-03-27 04:24



En Java 8, podrías hacer:

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

Algunas notas: la secuencia devuelta por Files.lines (a diferencia de la mayoría de las transmisiones) debe estar cerrado. Por las razones mencionado aquí Evito el uso forEach(). El extraño código (Iterable<String>) lines::iterator lanza un Stream a un Iterable.


20
2017-12-15 09:38



Lo que puede hacer es escanear todo el texto usando el Escáner y recorrer el texto línea por línea. Por supuesto, debe importar lo siguiente:

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

El escáner básicamente escanea todo el texto. El ciclo while se usa para recorrer todo el texto.

los .hasNextLine() función es un booleano que devuelve verdadero si todavía hay más líneas en el texto. los .nextLine() función le da una línea completa como una cadena que luego puede utilizar de la manera que desee. Tratar System.out.println(line) para imprimir el texto

Nota al margen: .txt es el texto del tipo de archivo.


19
2017-09-12 18:43



FileReader no le permitirá especificar la codificación, uso InputStreamReaderen cambio, si necesita especificarlo:

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

Si importó este archivo desde Windows, podría tener codificación ANSI (Cp1252), por lo que debe especificar la codificación.


17
2018-01-26 20:43



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

14
2018-04-09 00:52



Puedes usar la clase de escáner

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

9
2018-05-03 11:00



por Leyendo archivo con 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
2018-04-20 09:45



En Java 8, también hay una alternativa al uso Files.lines(). Si su fuente de entrada no es un archivo sino algo más abstracto como un Reader o un InputStream, usted puede corriente las líneas a través de BufferedReaders lines() método.

Por ejemplo:

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

llamará processLine() para cada línea de entrada leída por el BufferedReader.


8
2017-07-07 10:13