Чтение определенной строки из текстового файла в Java

Есть ли способ прочитать конкретную строку из текстового файла? В API или Apache Commons. Что-то вроде:

String readLine(File file, int lineNumber)

Я согласен, что это тривиально реализовать, но это не очень эффективно, особенно если файл очень большой.

9 ответов

Решение
String line = FileUtils.readLines(file).get(lineNumber);

будет делать, но у него все еще есть проблема эффективности.

В качестве альтернативы вы можете использовать:

 LineIterator it = IOUtils.lineIterator(
       new BufferedReader(new FileReader("file.txt")));
 for (int lineNumber = 0; it.hasNext(); lineNumber++) {
    String line = (String) it.next();
    if (lineNumber == expectedLineNumber) {
        return line;
    }
 }

Это будет немного более эффективно из-за буфера.

Взгляни на Scanner.skip(..) и попытаться пропустить целые строки (с помощью регулярного выражения). Я не могу сказать, будет ли это более эффективным - сравните это.

PS с эффективностью имею ввиду эффективность памяти

Не то, чтобы я знал.

Имейте в виду, что нет особой индексации в файлах относительно того, где начинается строка, поэтому любой вспомогательный метод будет настолько же эффективным, как:

BufferedReader r = new BufferedReader(new FileReader(file));
for (int i = 0; i < lineNumber - 1; i++)
{
   r.readLine();
}
return r.readLine();

(с соответствующей логикой обработки ошибок и закрытия ресурсов, конечно).

Если все строки, которые вы читали, имеют одинаковую длину, тогда вычисление может быть полезным.

Но в ситуации, когда строки имеют разную длину, я не думаю, что есть альтернатива их чтению по одному, пока количество строк не будет правильным.

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

Использование File Utils:

File fileFeatures = new File(
                "Homework1AdditionalFiles/jEdit4.3/jEdit4.3ListOfFeatureIDs.txt");
String line = (String) FileUtils.readLines(fileFeatures).get(lineNumber);

К сожалению, если вы не можете гарантировать, что каждая строка в файле имеет одинаковую длину, вам придется прочитать весь файл или, по крайней мере, до нужной вам строки.

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

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

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

Гуава имеет нечто подобное:

List<String> Files.readLines(File file, Charset charset);

Так что вы можете сделать

String line = Files.readLines(file, Charsets.UTF_8).get(lineNumber);

Согласно этому ответу, Java 8 позволяет нам извлекать определенные строки из файла. Примеры приведены в этом ответе.

Если вы собираетесь работать с одним и тем же файлом одинаково (ищите текст в определенной строке), вы можете проиндексировать ваш файл. Номер строки -> смещение.

Другие вопросы по тегам