Leer una línea en un número de línea dado de un archivo en Java

1. Información general

En este artículo rápido, veremos diferentes formas de leer una línea en un número de línea determinado dentro de un archivo.

2. Archivo de entrada

Comencemos creando un archivo simple llamado inputLines.txt que usaremos en todos nuestros ejemplos:

Line 1 Line 2 Line 3 Line 4 Line 5

3. Uso de BufferedReader

Veamos la conocida clase BufferedReader y su ventaja de no almacenar todo el archivo en la memoria.

Podemos leer un archivo línea por línea y detenernos cuando lo deseemos:

@Test public void givenFile_whenUsingBufferedReader_thenExtractedLineIsCorrect() { try (BufferedReader br = Files.newBufferedReader(Paths.get(FILE_PATH))) { for (int i = 0; i < 3; i++) { br.readLine(); } String extractedLine = br.readLine(); assertEquals("Line 4", extractedLine); } }

4. Usando el escáner

Otro enfoque similar que podemos adoptar es el uso de un escáner :

@Test public void givenFile_whenUsingScanner_thenExtractedLineIsCorrect() { try (Scanner scanner = new Scanner(new File(FILE_PATH))) { for (int i = 0; i < 3; i++) { scanner.nextLine(); } String extractedLine = scanner.nextLine(); assertEquals("Line 4", extractedLine); } }

Aunque en archivos pequeños, la diferencia entre BufferedReader y Scanner puede no ser perceptible, en archivos más grandes, el Scanner será más lento ya que también analiza y tiene un tamaño de búfer más pequeño.

5. Usando la API de archivos

5.1. Archivos pequeños

Podemos usar Files.readAllLines () de la API de archivos para leer fácilmente el contenido de un archivo en la memoria y extraer la línea que deseamos:

@Test public void givenSmallFile_whenUsingFilesAPI_thenExtractedLineIsCorrect() { String extractedLine = Files.readAllLines(Paths.get(FILE_PATH)).get(4); assertEquals("Line 5", extractedLine); }

5.2. Archivos grandes

Si necesitamos trabajar con archivos grandes, debemos usar el método lines , que devuelve un Stream para que podamos leer el archivo línea por línea:

@Test public void givenLargeFile_whenUsingFilesAPI_thenExtractedLineIsCorrect() { try (Stream lines = Files.lines(Paths.get(FILE_PATH))) { String extractedLine = lines.skip(4).findFirst().get(); assertEquals("Line 5", extractedLine); } }

6. Uso de Apache Commons IO

Otra opción es usar la clase FileUtils del paquete commons-io , que lee todo el archivo y devuelve las líneas como una lista de String s:

@Test public void givenFile_whenUsingFileUtils_thenExtractedLineIsCorrect() { ClassLoader classLoader = getClass().getClassLoader(); File file = new File(classLoader.getResource("linesInput.txt").getFile()); List lines = FileUtils.readLines(file, "UTF-8"); String extractedLine = lines.get(0); assertEquals("Line 1", extractedLine); }

También podemos usar la clase IOUtils para lograr el mismo resultado, excepto que esta vez, todo el contenido se devuelve como una cadena , y tenemos que dividirlo nosotros mismos:

@Test public void givenFile_whenUsingIOUtils_thenExtractedLineIsCorrect() { String fileContent = IOUtils.toString(new FileInputStream(FILE_PATH), StandardCharsets.UTF_8); String extractedLine = fileContent.split(System.lineSeparator())[0]; assertEquals("Line 1", extractedLine); }

7. Conclusión

En este artículo rápido, hemos repasado las formas más comunes de leer una línea en un número de línea determinado de un archivo.

Como de costumbre, los ejemplos están disponibles en GitHub.