Иногда было бы хорошо иметь перегрузку оператора, друг классы и множественное наследование.
Однако я все еще думаю, что это было хорошее решение. Если Java имел бы оператор, перегружающийся затем, мы никогда не могли бы быть уверены в значениях оператора, не просматривая исходный код. В настоящее время это не необходимо. И я думаю, что Ваш пример использования методов вместо перегрузки оператора также довольно читаем. Если Вы хотите сделать вещи более ясными, Вы могли бы всегда добавлять комментарий выше волосатых операторов.
// a = b + c
Complex a, b, c; a = b.add(c);
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 раз больше.
Буферизованного считывателя слишком много
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 () для одного символа не является оптимальным. см. здесь для примеров и измерений.
Вероятно, самым быстрым решением на чистой Java было бы чтение файла в виде байтов с использованием канала NIO в большой буфер ByteBuffer. Затем, используя свои знания о схемах кодирования файлов, подсчитайте закодированные байты CR и / или NL согласно соответствующему соглашению о разделителях строк.
Ключи к максимальной пропускной способности:
Фактический код слишком сложен, чтобы я мог писать на лету. Кроме того, OP не требует самого быстрого решения.
Считайте файл построчно и увеличивайте значение счетчика для каждой строки, пока не прочитаете весь файл.
Попробуйте команду unix «wc». Я не имею в виду использовать его, я имею в виду загрузить исходный код и посмотреть, как они это делают. Вероятно, это в c, но вы можете легко перенести поведение на java. Проблема с созданием собственного состоит в том, чтобы учесть конечную проблему cr / lf.
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;
}
}
}
Все предыдущие ответы предлагают прочитать весь файл и подсчитать количество новых строк, которые вы найдете при этом. Вы прокомментировали некоторые из них как «неэффективные», но это единственный способ сделать это. «Строка» - это не что иное, как простой символ внутри файла. И чтобы посчитать этот символ, вы должны взглянуть на каждый символ в файле.
Извините, но у вас нет выбора. : -)
Это настолько эффективно, насколько это возможно, буферизованное двоичное чтение, без преобразования строк,
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);
Прочтите файл и подсчитайте количество символов новой строки. Простой способ прочитать файл на Java по одной строке за раз - это класс java.util.Scanner .
используйте 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();
}
}
Если уже опубликованные ответы недостаточно быстры, вам, вероятно, придется искать решение, специфичное для вашей конкретной проблемы.
Например, если эти текстовые файлы представляют собой только журналы добавлены, и вам необходимо регулярно знать, сколько строк в них можно создать для индекса. Этот индекс будет содержать количество строк в файле, дату последнего изменения файла и размер файла. Это позволит вам пересчитать количество строк в файле, пропустив все строки, которые вы уже видели, и просто прочитав новые строки.