web-dev-qa-db-fra.com

Comment lire une ligne spécifique en utilisant le numéro de ligne spécifique d'un fichier en Java?

En Java, existe-t-il une méthode pour lire une ligne particulière à partir d'un fichier? Par exemple, lisez la ligne 32 ou tout autre numéro de ligne.

85
trinity

Si vous ne connaissez pas les lignes du fichier, vous ne pouvez pas accéder directement à la 32e ligne sans lire les 31 lignes précédentes.

Cela est vrai pour toutes les langues et tous les systèmes de fichiers modernes.

Donc, effectivement, vous lirez simplement les lignes jusqu'à ce que vous ayez trouvé la 32e.

69
Joachim Sauer

Solution Java 8:

Pour les petits fichiers:

String line32 = Files.readAllLines(Paths.get("file.txt")).get(32)

Pour les gros fichiers:

try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    line32 = lines.skip(31).findFirst().get();
}
90
aioobe

Pas à ma connaissance, mais ce que vous pourriez faire est de parcourir les 31 premières lignes sans rien faire à l'aide de la fonction readline () de BufferedReader

FileInputStream fs= new FileInputStream("someFile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
for(int i = 0; i < 31; ++i)
  br.readLine();
String lineIWant = br.readLine();
37
Chris Thompson

Joachim a raison, bien sûr, et une implémentation alternative à celle de Chris (pour les petits fichiers uniquement, car elle charge tout le fichier) pourrait consister à utiliser commons-io d’Apache (même s’il est discutable que vous ne voudriez pas introduire une nouvelle dépendance ceci, si vous le trouvez utile pour d'autres choses aussi, cela pourrait avoir un sens).

Par exemple:

String line32 = (String) FileUtils.readLines(file).get(31);

http://commons.Apache.org/io/api-release/org/Apache/commons/io/FileUtils.html#readLines (Java.io.File , Java.lang.String)

15
Charlie Collins

Vous pouvez essayer indexed-file-reader (Apache License 2.0). La classe IndexedFileReader a une méthode appelée readLines (int de, int à) qui retourne un SortedMap dont la clé est le numéro de la ligne et la valeur celle qui a été lue.

Exemple:

File file = new File("src/test/resources/file.txt");
reader = new IndexedFileReader(file);

lines = reader.readLines(6, 10);
assertNotNull("Null result.", lines);
assertEquals("Incorrect length.", 5, lines.size());
assertTrue("Incorrect value.", lines.get(6).startsWith("[6]"));
assertTrue("Incorrect value.", lines.get(7).startsWith("[7]"));
assertTrue("Incorrect value.", lines.get(8).startsWith("[8]"));
assertTrue("Incorrect value.", lines.get(9).startsWith("[9]"));
assertTrue("Incorrect value.", lines.get(10).startsWith("[10]"));      

L'exemple ci-dessus lit un fichier texte composé de 50 lignes au format suivant:

[1] The quick brown fox jumped over the lazy dog ODD
[2] The quick brown fox jumped over the lazy dog EVEN

Disclamer: J'ai écrit cette bibliothèque

10
jramoyo

Bien que, comme indiqué dans d'autres réponses, il n'est pas possible d'obtenir la ligne exacte sans connaître le décalage (pointeur) auparavant. J'ai donc réalisé cela en créant un fichier d'index temporaire qui stockerait les valeurs de décalage de chaque ligne. Si le fichier est suffisamment petit, vous pouvez simplement stocker les index (offset) en mémoire sans avoir besoin d'un fichier séparé pour cela.

The offsets can be calculated by using the RandomAccessFile

    RandomAccessFile raf = new RandomAccessFile("myFile.txt","r"); 
    //above 'r' means open in read only mode
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    String cur_line = "";
    while((cur_line=raf.readLine())!=null)
    {
    arrayList.add(raf.getFilePointer());
    }
    //Print the 32 line
    //Seeks the file to the particular location from where our '32' line starts
    raf.seek(raf.seek(arrayList.get(31));
    System.out.println(raf.readLine());
    raf.close();

Visitez également les Java pour plus d'informations: https://docs.Oracle.com/javase/8/docs/api/Java/io/RandomAccessFile.html#mode

Complexité : C’est O(n) car il lit l’ensemble du fichier une fois. Veuillez prendre en compte les besoins en mémoire S'il est trop volumineux pour être en mémoire, créez un fichier temporaire qui stocke les décalages au lieu de ArrayList, comme indiqué ci-dessus.

Note : Si tout ce que vous voulez dans la ligne '32', il vous suffit d'appeler readLine () également disponible via les temps des autres classes '32'. L'approche ci-dessus est utile si vous souhaitez obtenir plusieurs fois une ligne spécifique (en fonction du numéro de ligne du cours).

Merci !

5
ShankarDaruga

Non, à moins que dans ce format de fichier, les longueurs de ligne soient prédéterminées (par exemple, toutes les lignes de longueur fixe), vous devrez itérer ligne par ligne pour les compter.

4
b.roth

Autrement.

try (BufferedReader reader = Files.newBufferedReader(
        Paths.get("file.txt"), StandardCharsets.UTF_8)) {
    List<String> line = reader.lines()
                              .skip(31)
                              .limit(1)
                              .collect(Collectors.toList());

    line.stream().forEach(System.out::println);
}
4
rhel.user

Si vous parlez d'un fichier texte, il n'y a vraiment aucun moyen de le faire sans lire toutes les lignes qui le précèdent - Après tout, les lignes sont déterminées par la présence d'une nouvelle ligne, elle doit donc être lue.

Utilisez un flux prenant en charge readline, lisez simplement les premières lignes X-1 et exportez les résultats, puis traitez la suivante.

2
Uri

Dans Java 8,

Pour les petits fichiers:

String line = Files.readAllLines(Paths.get("file.txt")).get(n);

Pour les gros fichiers:

String line;
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    line = lines.skip(n).findFirst().get();
}

Dans Java 7

String line;
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    for (int i = 0; i < n; i++)
        br.readLine();
    line = br.readLine();
}

Source: lecture de la nième ligne du fichier

2
Sid

Cela fonctionne pour moi: j'ai combiné la réponse de Lecture d'un fichier texte simple

Mais au lieu de renvoyer une chaîne, je retourne une liste LinkedList of Strings. Ensuite, je peux sélectionner la ligne que je veux.

public static LinkedList<String> readFromAssets(Context context, String filename) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filename)));
    LinkedList<String>linkedList = new LinkedList<>();
    // do reading, usually loop until end of file reading
    StringBuilder sb = new StringBuilder();
    String mLine = reader.readLine();
    while (mLine != null) {
        linkedList.add(mLine);
        sb.append(mLine); // process line
        mLine = reader.readLine();


    }
    reader.close();
    return linkedList;
}
1
Tachenko

Utilisez ce code:

import Java.nio.file.Files;

import Java.nio.file.Paths;

public class FileWork 
{

    public static void main(String[] args) throws IOException {

        String line = Files.readAllLines(Paths.get("D:/abc.txt")).get(1);

        System.out.println(line);  
    }

}
1
Usman Yaqoob

Vous pouvez utiliser LineNumberReader au lieu de BufferedReader. Passer par l'api. Vous pouvez trouver les méthodes setLineNumber et getLineNumber.

0
Raghavendra

vous pouvez utiliser la fonction skip () pour ignorer les lignes du début.

public static void readFile(String filePath, long lineNum) {
    List<String> list = new ArrayList<>();
    long totalLines, startLine = 0;

    try (Stream<String> lines = Files.lines(Paths.get(filePath))) {
        totalLines = Files.lines(Paths.get(filePath)).count();
        startLine = totalLines - lineNum;
        // Stream<String> line32 = lines.skip(((startLine)+1));

        list = lines.skip(startLine).collect(Collectors.toList());
        // lines.forEach(list::add);
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    list.forEach(System.out::println);

}
0
Neelay Solanki

Vous pouvez également consulter LineNumberReader, sous-classe de BufferedReader. En plus de la méthode readline, il existe également des méthodes setter/getter pour accéder au numéro de ligne. Très utile pour garder une trace du nombre de lignes lues lors de la lecture des données d’un fichier.

0
Ankur Shanbhag
public String readLine(int line){
        FileReader tempFileReader = null;
        BufferedReader tempBufferedReader = null;
        try { tempFileReader = new FileReader(textFile); 
        tempBufferedReader = new BufferedReader(tempFileReader);
        } catch (Exception e) { }
        String returnStr = "ERROR";
        for(int i = 0; i < line - 1; i++){
            try { tempBufferedReader.readLine(); } catch (Exception e) { }
        }
        try { returnStr = tempBufferedReader.readLine(); }  catch (Exception e) { }

        return returnStr;
    }
0
Cooper Scott