«1. Обзор

В этой быстрой статье мы рассмотрим различные способы чтения строки с заданным номером строки внутри файла.

2. Входной файл

Давайте начнем с создания простого файла с именем inputLines.txt, который мы будем использовать во всех наших примерах:

Line 1
Line 2
Line 3
Line 4
Line 5

3. Использование BufferedReader

Давайте посмотрим на хорошо известный класс BufferedReader и его преимущество в том, что он не сохраняет весь файл в памяти.

Мы можем читать файл построчно и останавливаться, когда захотим:

@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. Использование сканера

Другой аналогичный подход, который мы можем использовать, это использование сканера:

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

Хотя на небольшом файлы, разница между BufferedReader и Scanner может быть незаметна, с файлами большего размера Scanner будет работать медленнее, поскольку он также выполняет синтаксический анализ и имеет меньший размер буфера.

5. Использование File API

5.1. Маленькие файлы

Мы можем использовать Files.readAllLines() из File API, чтобы легко прочитать содержимое файла в память и извлечь нужную строку:

@Test
public void givenSmallFile_whenUsingFilesAPI_thenExtractedLineIsCorrect() {
    String extractedLine = Files.readAllLines(Paths.get(FILE_PATH)).get(4);

    assertEquals("Line 5", extractedLine);
}

5.2. Большие файлы

Если нам нужно работать с большими файлами, мы должны использовать метод lines, который возвращает поток, чтобы мы могли читать файл построчно:

@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. Использование Apache Commons IO ~~ ~ Другим вариантом является использование класса FileUtils пакета commons-io, который считывает весь файл и возвращает строки в виде списка строк:

Мы также можем использовать класс IOUtils для достижения того же результата, за исключением на этот раз все содержимое возвращается в виде строки, и мы должны выполнить разбиение самостоятельно:

@Test
public void givenFile_whenUsingFileUtils_thenExtractedLineIsCorrect() {
    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("linesInput.txt").getFile());

    List<String> lines = FileUtils.readLines(file, "UTF-8");

    String extractedLine = lines.get(0);
    assertEquals("Line 1", extractedLine);
}

7. Заключение

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

В этой быстрой статье мы рассмотрели наиболее распространенные способы чтения строка с заданным номером строки из файла.

Как обычно, примеры доступны на GitHub.

«