Перейти к основному содержимому

Найдите количество строк в файле с помощью Java

· 4 мин. чтения

1. Обзор

В этом руководстве мы узнаем , как найти количество строк в файле с помощью Java с помощью стандартных API ввода-вывода Java, Google Guav a и библиотеки ввода-вывода Apache Commons .

2. Файлы NIO2

Обратите внимание, что в этом руководстве мы будем использовать следующие примеры значений в качестве имени входного файла и общего количества строк:

static final String INPUT_FILE_NAME = "src/main/resources/input.txt";
static final int NO_OF_LINES = 45;

Java 7 внесла множество улучшений в существующие библиотеки ввода-вывода и упаковала их в NIO2:

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

@Test
public void whenUsingNIOFiles_thenReturnTotalNumberOfLines() throws IOException {
try (Stream<String> fileStream = Files.lines(Paths.get(INPUT_FILE_NAME))) {
int noOfLines = (int) fileStream.count();
assertEquals(NO_OF_LINES, noOfLines);
}
}

Или просто используя метод Files#readAllLines :

@Test
public void whenUsingNIOFilesReadAllLines_thenReturnTotalNumberOfLines() throws IOException {
List<String> fileStream = Files.readAllLines(Paths.get(INPUT_FILE_NAME));
int noOfLines = fileStream.size();
assertEquals(NO_OF_LINES, noOfLines);
}

3. Файловый канал NIO

Теперь давайте проверим FileChannel, высокопроизводительную альтернативу Java NIO для чтения количества строк:

@Test
public void whenUsingNIOFileChannel_thenReturnTotalNumberOfLines() throws IOException {
int noOfLines = 1;
try (FileChannel channel = FileChannel.open(Paths.get(INPUT_FILE_NAME), StandardOpenOption.READ)) {
ByteBuffer byteBuffer = channel.map(MapMode.READ_ONLY, 0, channel.size());
while (byteBuffer.hasRemaining()) {
byte currentByte = byteBuffer.get();
if (currentByte == '\n')
noOfLines++;
}
}
assertEquals(NO_OF_LINES, noOfLines);
}

Хотя FileChannel был представлен в JDK 4, приведенное выше решение работает только с JDK 7 или более поздней версии .

4. Файлы Гуавы Google

Альтернативной сторонней библиотекой может быть класс Google Guava Files . Этот класс также можно использовать для подсчета общего количества строк аналогично тому, что мы видели с Files#readAllLines .

Давайте начнем с добавления зависимости guava в наш pom.xml :

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>

И затем мы можем использовать readLines для получения списка строк файла:

@Test
public void whenUsingGoogleGuava_thenReturnTotalNumberOfLines() throws IOException {
List<String> lineItems = Files.readLines(Paths.get(INPUT_FILE_NAME)
.toFile(), Charset.defaultCharset());
int noOfLines = lineItems.size();
assertEquals(NO_OF_LINES, noOfLines);
}

5. Apache Commons IO FileUtils

Теперь давайте посмотрим на Apache Commons IO FileUtils API, параллельное решение для Guava.

Чтобы использовать библиотеку, мы должны включить зависимость commons-io в pom.xml :

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>

В этот момент мы можем использовать FileUtils#lineIterator Apache Commons IO , который очищает для нас некоторые операции с файлами:

@Test
public void whenUsingApacheCommonsIO_thenReturnTotalNumberOfLines() throws IOException {
int noOfLines = 0;
LineIterator lineIterator = FileUtils.lineIterator(new File(INPUT_FILE_NAME));
while (lineIterator.hasNext()) {
lineIterator.nextLine();
noOfLines++;
}
assertEquals(NO_OF_LINES, noOfLines);
}

Как мы видим, это немного более многословно, чем решение Google Guava.

6. Буферизированный читатель

Итак, как насчет олдскульных способов? Если мы не на JDK 7 и не можем использовать стороннюю библиотеку, у нас есть BufferedReader :

@Test
public void whenUsingBufferedReader_thenReturnTotalNumberOfLines() throws IOException {
int noOfLines = 0;
try (BufferedReader reader = new BufferedReader(new FileReader(INPUT_FILE_NAME))) {
while (reader.readLine() != null) {
noOfLines++;
}
}
assertEquals(NO_OF_LINES, noOfLines);
}

7. LineNumberReader

Или мы можем использовать LineNumberReader, прямой подкласс BufferedReader , который чуть менее многословен:

@Test
public void whenUsingLineNumberReader_thenReturnTotalNumberOfLines() throws IOException {
try (LineNumberReader reader = new LineNumberReader(new FileReader(INPUT_FILE_NAME))) {
reader.skip(Integer.MAX_VALUE);
int noOfLines = reader.getLineNumber() + 1;
assertEquals(NO_OF_LINES, noOfLines);
}
}

Здесь мы вызываем метод пропуска , чтобы перейти к концу файла, и добавляем 1 к общему количеству подсчитанных строк, поскольку нумерация строк начинается с 0.

8. Сканер

И, наконец, если мы уже используем Scanner как часть более крупного решения, это также может решить проблему для нас:

@Test
public void whenUsingScanner_thenReturnTotalNumberOfLines() throws IOException {
try (Scanner scanner = new Scanner(new FileReader(INPUT_FILE_NAME))) {
int noOfLines = 0;
while (scanner.hasNextLine()) {
scanner.nextLine();
noOfLines++;
}
assertEquals(NO_OF_LINES, noOfLines);
}
}

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

В этом руководстве мы рассмотрели различные способы определения количества строк в файле с помощью Java. Поскольку основная цель всех этих API — не подсчет количества строк в файле, рекомендуется выбрать правильное решение для наших нужд.

Как всегда, исходный код этого руководства доступен на GitHub .