Pregunta ¿Cómo leer una línea específica usando el número de línea específico de un archivo en Java?


En Java, ¿hay algún método para leer una línea particular de un archivo? Por ejemplo, lea la línea 32 o cualquier otro número de línea.


74
2018-02-22 17:30


origen


Respuestas:


A menos que tenga conocimientos previos sobre las líneas del archivo, no hay forma de acceder directamente a la línea 32 sin leer las 31 líneas anteriores.

Eso es cierto para todos los idiomas y todos los sistemas de archivos modernos.

Entonces, efectivamente, solo leerás las líneas hasta que encuentres la 32ª.


61
2018-02-22 17:32



Solución Java 8:

Para archivos pequeños:

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

Para archivos grandes:

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

76
2018-04-14 21:08



No es que yo sepa, pero lo que podrías hacer es recorrer las primeras 31 líneas sin hacer nada usando la función 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();

32
2018-02-22 17:35



Joachim tiene razón, por supuesto, y una implementación alternativa para Chris (para archivos pequeños solo porque carga todo el archivo) podría ser el uso de commons-io de Apache (aunque posiblemente podría no querer introducir una nueva dependencia solo para esto, si lo encuentras útil para otras cosas también, podría tener sentido).

Por ejemplo:

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)


14
2018-02-22 21:45



Puedes probar lector de archivos indexados (Licencia de Apache 2.0). La clase IndexedFileReader tiene un método llamado readLines (int from, int to) que devuelve un SortedMap cuya clave es el número de línea y el valor es la línea que se leyó.

Ejemplo:

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]"));      

El ejemplo anterior lee un archivo de texto compuesto por 50 líneas en el siguiente formato:

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

Descargo de responsabilidad: escribí esta biblioteca


8
2018-05-22 05:27



Aunque como se dijo en otras respuestas, no es posible llegar a la línea exacta sin conocer el desplazamiento (puntero) anterior. Entonces, logré esto creando un archivo de índice temporal que almacenaría los valores de compensación de cada línea. Si el archivo es lo suficientemente pequeño, puede simplemente almacenar los índices (desplazamiento) en la memoria sin necesidad de un archivo separado para ello.

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

También visite los documentos de Java para más información: https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode

Complejidad : Esto es O (n) ya que lee todo el archivo una vez. Tenga en cuenta los requisitos de memoria. Si es demasiado grande para estar en la memoria, cree un archivo temporal que almacene los desplazamientos en lugar de ArrayList como se muestra arriba.

Nota : Si todo lo que quiere en la línea '32', solo tiene que llamar a readLine () también disponible a través de otras clases '32' veces. El enfoque anterior es útil si desea obtener una línea específica (en función del número de línea del curso) varias veces.

Gracias !


4
2017-09-06 11:39



No, a menos que en ese formato de archivo las longitudes de línea estén predeterminadas (por ejemplo, todas las líneas con una longitud fija), deberá iterar línea por línea para contarlas.


3
2018-02-22 17:50



Si está hablando de un archivo de texto, entonces realmente no hay forma de hacerlo sin leer todas las líneas que lo preceden. Después de todo, las líneas están determinadas por la presencia de una línea nueva, por lo que debe leerse.

Utilice una secuencia que sea compatible con readline, y simplemente lea las primeras líneas X-1 y vacíe los resultados, luego procese la siguiente.


2
2018-02-22 17:33



De otra manera.

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

2
2017-12-12 16:48



Esto funciona para mi: He combinado la respuesta de Leyendo un archivo de texto simple

Pero en lugar de devolver una Cadena, estoy devolviendo una Lista Vinculada de Cadenas. Entonces puedo seleccionar la línea que quiero.

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
2017-07-06 16:59