Как прочитать конкретную строку, используя определенный номер строки из файла в Java? - PullRequest
84 голосов
/ 22 февраля 2010

В Java есть какой-либо метод для чтения определенной строки из файла? Например, прочитайте строку 32 или любой другой номер строки.

Ответы [ 17 ]

88 голосов
/ 15 апреля 2015

Java 8 решение:

Для небольших файлов:

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

Для больших файлов:

try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    line32 = lines.skip(31).findFirst().get();
}
69 голосов
/ 22 февраля 2010

Если у вас нет предыдущих знаний о строках в файле, невозможно получить прямой доступ к 32-й строке без чтения 31 предыдущих строк.

Это верно для всех языков и всех современных файловых систем.

Таким образом, вы будете просто читать строки, пока не найдете 32-ю.

37 голосов
/ 22 февраля 2010

Не то, что я знаю, но то, что вы могли бы сделать, это перебрать первые 31 строку, ничего не делая, используя функцию readline () 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();
15 голосов
/ 23 февраля 2010

Joachim, конечно, прав, и альтернативная реализация Chris '(для небольших файлов только потому, что он загружает весь файл) может заключаться в использовании commons-io из Apache (хотя, возможно, вы не захотите вводить новый зависимость только для этого, если вы найдете это полезным для других вещей, хотя, это может иметь смысл).

Например:

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)

10 голосов
/ 22 мая 2013

Вы можете попробовать indexed-file-reader (Apache License 2.0). Класс IndexedFileReader имеет метод с именем readLines (int from, int to) , который возвращает SortedMap, ключом которого является номер строки и значением является строка, которая была прочитана.

Пример:

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

Приведенный выше пример читает текстовый файл, состоящий из 50 строк, в следующем формате:

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

Disclamer: я написал эту библиотеку

5 голосов
/ 06 сентября 2017

Хотя, как сказано в других ответах, невозможно получить точную строку, не зная смещения (указателя) раньше.Итак, я добился этого, создав временный индексный файл, в котором будут храниться значения смещения каждой строки.Если файл достаточно мал, вы можете просто сохранить индексы (смещение) в памяти, не требуя для этого отдельного файла.

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

Также посетите документацию по Java для получения дополнительной информации: https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode

Сложность : Это O (n), поскольку он читает весь файл один раз.Пожалуйста, помните о требованиях к памяти.Если он слишком большой, чтобы находиться в памяти, создайте временный файл, в котором вместо ArrayList будут храниться смещения, как показано выше.

Примечание : если все, что вы хотите в строке '32', выпросто нужно вызвать readLine (), также доступную через другие классы, 32 раза.Приведенный выше подход полезен, если вы хотите получить определенную строку (на основе номера строки, конечно) несколько раз.

Спасибо!

4 голосов
/ 22 февраля 2010

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

3 голосов
/ 12 декабря 2016

Другой способ.

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 голосов
/ 22 февраля 2010

Если вы говорите о текстовом файле, то на самом деле нет способа сделать это, не прочитав все строки, предшествующие ему. В конце концов, строки определяются наличием новой строки, поэтому ее нужно прочитать.

Используйте поток, который поддерживает readline, и просто прочитайте первые строки X-1 и сохраните результаты, а затем обработайте следующую.

2 голосов
/ 22 февраля 2018

В Java 8,

Для небольших файлов:

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

Для больших файлов:

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

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

Источник: Чтение n-й строки из файла

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...