Question Comment lire un gros fichier texte ligne par ligne en utilisant Java?


J'ai besoin de lire un gros fichier texte d'environ 5-6 Go ligne par ligne en utilisant Java.

Comment puis-je le faire rapidement?


681
2018-05-03 10:53


origine


Réponses:


Un modèle commun est d'utiliser

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

Vous pouvez lire les données plus rapidement si vous supposez qu'il n'y a pas d'encodage de caractères. par exemple. ASCII-7 mais ça ne fera pas beaucoup de différence. Il est fort probable que ce que vous ferez avec les données prendra beaucoup plus de temps.

EDIT: Un modèle moins commun à utiliser qui évite la portée de line fuite.

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

UPDATE: En Java 8, vous pouvez faire

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

Remarque: vous devez placer le flux dans un bloc try-with-resource pour vous assurer que la méthode #close est appelée, sinon le handle de fichier sous-jacent n'est jamais fermé jusqu'à ce que GC le fasse beaucoup plus tard.


860
2018-05-03 11:07



Regardez ce blog:

La taille de la mémoire tampon peut être spécifiée, ou   la taille par défaut peut être utilisée. le   par défaut est assez grand pour la plupart   fins.

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



Une fois que  est sorti (Mars 2014), vous serez en mesure d'utiliser des flux:

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

Imprimer toutes les lignes du fichier:

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

78
2017-07-25 18:58



Voici un exemple avec la gestion complète des erreurs et la spécification de charset de support pour pré-Java 7. Avec Java 7, vous pouvez utiliser la syntaxe try-with-resources, ce qui rend le code plus propre.

Si vous voulez juste le jeu de caractères par défaut, vous pouvez ignorer InputStream et utiliser 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 */ } }
}

Voici la version Groovy, avec gestion complète des erreurs:

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, vous pouvez faire:

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

Quelques notes: Le flux retourné par Files.lines (contrairement à la plupart des flux) doit être fermé. Pour les raisons mentionné ici J'évite d'utiliser forEach(). Le code étrange (Iterable<String>) lines::iterator lance un flux vers un itératif.


20
2017-12-15 09:38



Ce que vous pouvez faire est de scanner le texte entier en utilisant Scanner et de parcourir le texte ligne par ligne. Bien sûr, vous devriez importer ce qui suit:

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

Le scanner scanne tout le texte. La boucle while est utilisée pour traverser le texte entier.

le .hasNextLine() function est un booléen qui renvoie true s'il y a encore plus de lignes dans le texte. le .nextLine() La fonction vous donne une ligne entière en tant que chaîne que vous pouvez ensuite utiliser comme vous le souhaitez. Essayer System.out.println(line) pour imprimer le texte.

Side Note: .txt est le texte du type de fichier.


19
2017-09-12 18:43



FileReader ne vous laissera pas spécifier l'encodage, utilisez InputStreamReaderAu lieu de cela, si vous avez besoin de le spécifier:

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 vous avez importé ce fichier à partir de Windows, il est possible qu'il ait un codage ANSI (Cp1252), vous devez donc spécifier l'encodage.


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



Vous pouvez utiliser la classe Scanner

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

9
2018-05-03 11:00