web-dev-qa-db-fra.com

Comment lire un fichier texte volumineux ligne par ligne avec Java?

J'ai besoin de lire un fichier texte volumineux d'environ 5 à 6 Go, ligne par ligne, avec Java.

Comment puis-je faire cela rapidement? 

746
manoj singh

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 cela 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 qui fuit.

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 descripteur de fichier sous-jacent n'est jamais fermé jusqu'à ce que GC le fasse beaucoup plus tard.

953
Peter Lawrey

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 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
fstream.close();
133
Naveed

Une fois que Java-8 est sorti (mars 2014), vous pourrez 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);
}
82
msayag

Voici un exemple de gestion complète des erreurs et de prise en charge de la spécification du jeu de caractères pour les versions antérieures à Java 7. Java 7 permet d’utiliser la syntaxe try-with-resources, qui permet de nettoyer le code.

Si vous ne voulez que 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;
    }
}
35
DarkStar

En Java 8, vous pouvez faire:

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

Quelques remarques: Le flux renvoyé par Files.lines (contrairement à la plupart des flux) doit être fermé. Pour les raisons mentionnées ici j’évite d’utiliser forEach(). Le code étrange (Iterable<String>) lines::iterator jette un flux vers un itérable.

21
Aleksandr Dubinsky

Ce que vous pouvez faire est d’analyser tout le texte à l’aide de Scanner et de parcourir le texte ligne par ligne . Vous devez bien entendu importer les éléments suivants:

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 fondamentalement tout le texte. La boucle while est utilisée pour parcourir tout le texte.

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

Note latérale: .txt est le texte du type de fichier.

19
iskandarchacra

FileReader ne vous laissera pas spécifier le codage, utilisez InputStreamReaderinstead si vous devez 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 soit doté du codage ANSI (Cp1252), vous devez donc spécifier le codage. 

17
live-love

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

J'ai documenté et testé 10 façons différentes de lire un fichier en Java puis je les ai exécutées les unes contre les autres en les faisant lire dans des fichiers de test de 1 Ko à 1 Go. Voici les 3 méthodes de lecture de fichier les plus rapides pour lire un fichier de test de 1 Go.

Notez que lors des tests de performance, je n’ai rien généré sur la console car cela ralentirait vraiment le test. Je voulais juste tester la vitesse de lecture brute.

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

Testé en Java 7, 8, 9. C'était globalement la méthode la plus rapide. La lecture d'un fichier de 1 Go a été constamment inférieure à 1 seconde.

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

Cela a été testé avec succès en Java 8 et 9, mais cela ne fonctionnera pas en raison de l’absence de prise en charge des expressions lambda. Il a fallu environ 3,5 secondes pour lire un fichier de 1 Go, ce qui l'a placé à la deuxième place en ce qui concerne la lecture de fichiers plus volumineux.

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

Testé pour fonctionner en Java 7, 8, 9. Cela a pris environ 4,5 secondes pour lire un fichier de test de 1 Go.

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

Vous pouvez trouver le classement complet des 10 méthodes de lecture de fichier ici .

11
gomisha

Pour Lecture de fichier avec 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

Vous pouvez utiliser la classe Scanner

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

En Java 8, il existe également une alternative à l’utilisation de Files.lines() . Si votre source d'entrée n'est pas un fichier mais quelque chose de plus abstrait comme Reader ou InputStream, vous pouvez stream les lignes via la méthode BufferedReaders lines().

Par exemple:

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

appellera processLine() pour chaque ligne d’entrée lue par la BufferedReader.

8
Rüdiger Herrmann

Vous devez utiliser la méthode readLine() dans class BufferedReader. Créez un nouvel objet à partir de cette classe, utilisez cette méthode sur lui et enregistrez-le en chaîne.

BufferReader Javadoc

7
Master C

Java-9:

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

Le moyen clair pour y parvenir,

Par exemple:

Si vous avez dataFile.txt sur votre répertoire actuel

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

La sortie comme ci-dessous,  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");
}

Ça marche pour moi. J'espère que cela vous aidera aussi.

3
Dipendra Ghatal

Je fais habituellement la routine de lecture simple: 

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
Binkan Salaryman

en utilisantorg.Apache.commons.iopackage a donné plus de performances, en particulier dans le code existant qui utilise Java 6 et inférieur.
Java7 a une meilleure API avec moins d'exceptions Traitement et des méthodes plus utiles 

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

Vous pouvez utiliser des flux pour le faire plus précisément:

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

Vous pouvez également utiliser 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();
}
0
To Kra

Vous pouvez utiliser ce code:

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