Как я могу получить количество строки в файле эффективным способом? [дубликат]

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

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

// a = b + c
Complex a, b, c; a = b.add(c);
67
задан Telemachus 14 August 2009 в 14:00
поделиться

11 ответов

BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
int lines = 0;
while (reader.readLine() != null) lines++;
reader.close();

Обновление: Чтобы ответить на поднятый здесь вопрос о производительности, я провел измерение. Первое: 20 000 строк - это слишком мало, чтобы программа работала в течение заметного времени. Я создал текстовый файл с 5 миллионами строк. Это решение (запущенное с java без параметров, таких как -server или -XX-options) потребовало около 11 секунд на моем ящике. То же самое с wc -l (инструмент командной строки UNIX для подсчета строк), 11 секунд. Решению, считывающему каждый символ и ищущему '\ n', требовалось 104 секунды, что в 9-10 раз больше.

106
ответ дан 24 November 2019 в 14:25
поделиться

Буферизованного считывателя слишком много

Reader r = new FileReader("f.txt");

int count = 0;
int nextchar = 0;
while (nextchar != -1){
        nextchar = r.read();
        if (nextchar == Character.getNumericValue('\n') ){
            count++;
        }
    }

Мои поиски простого примера привели к тому, что на самом деле он довольно плох. многократный вызов read () для одного символа не является оптимальным. см. здесь для примеров и измерений.

-2
ответ дан 24 November 2019 в 14:25
поделиться

Вероятно, самым быстрым решением на чистой Java было бы чтение файла в виде байтов с использованием канала NIO в большой буфер ByteBuffer. Затем, используя свои знания о схемах кодирования файлов, подсчитайте закодированные байты CR и / или NL согласно соответствующему соглашению о разделителях строк.

Ключи к максимальной пропускной способности:

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

Фактический код слишком сложен, чтобы я мог писать на лету. Кроме того, OP не требует самого быстрого решения.

-1
ответ дан 24 November 2019 в 14:25
поделиться

Считайте файл построчно и увеличивайте значение счетчика для каждой строки, пока не прочитаете весь файл.

0
ответ дан 24 November 2019 в 14:25
поделиться

Попробуйте команду unix «wc». Я не имею в виду использовать его, я имею в виду загрузить исходный код и посмотреть, как они это делают. Вероятно, это в c, но вы можете легко перенести поведение на java. Проблема с созданием собственного состоит в том, чтобы учесть конечную проблему cr / lf.

1
ответ дан 24 November 2019 в 14:25
поделиться

Quick and dirty, but it does the job:

import java.io.*;

public class Counter {

    public final static void main(String[] args) throws IOException {
        if (args.length > 0) {
            File file = new File(args[0]);
            System.out.println(countLines(file));
        }
    }

    public final static int countLines(File file) throws IOException {
        ProcessBuilder builder = new ProcessBuilder("wc", "-l", file.getAbsolutePath());
        Process process = builder.start();
        InputStream in = process.getInputStream();
        LineNumberReader reader = new LineNumberReader(new InputStreamReader(in));
        String line = reader.readLine();
        if (line != null) {
            return Integer.parseInt(line.trim().split(" ")[0]);
        } else {
            return -1;
        }
    }

}
2
ответ дан 24 November 2019 в 14:25
поделиться

Все предыдущие ответы предлагают прочитать весь файл и подсчитать количество новых строк, которые вы найдете при этом. Вы прокомментировали некоторые из них как «неэффективные», но это единственный способ сделать это. «Строка» - это не что иное, как простой символ внутри файла. И чтобы посчитать этот символ, вы должны взглянуть на каждый символ в файле.

Извините, но у вас нет выбора. : -)

2
ответ дан 24 November 2019 в 14:25
поделиться

Это настолько эффективно, насколько это возможно, буферизованное двоичное чтение, без преобразования строк,

FileInputStream stream = new FileInputStream("/tmp/test.txt");
byte[] buffer = new byte[8192];
int count = 0;
int n;
while ((n = stream.read(buffer)) > 0) {
    for (int i = 0; i < n; i++) {
        if (buffer[i] == '\n') count++;
    }
}
stream.close();
System.out.println("Number of lines: " + count);
4
ответ дан 24 November 2019 в 14:25
поделиться

Прочтите файл и подсчитайте количество символов новой строки. Простой способ прочитать файл на Java по одной строке за раз - это класс java.util.Scanner .

4
ответ дан 24 November 2019 в 14:25
поделиться

используйте LineNumberReader

что-то вроде

public static int countLines(File aFile) throws IOException {
    LineNumberReader reader = null;
    try {
        reader = new LineNumberReader(new FileReader(aFile));
        while ((reader.readLine()) != null);
        return reader.getLineNumber();
    } catch (Exception ex) {
        return -1;
    } finally { 
        if(reader != null) 
            reader.close();
    }
}
32
ответ дан 24 November 2019 в 14:25
поделиться

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

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

2
ответ дан 24 November 2019 в 14:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: