Намерете броя на редовете във файл, използвайки Java

1. Общ преглед

В този урок ще научим как да намерим броя на редовете във файл с помощта на Java с помощта на стандартни Java IO API, Google Guav a и Apache Commons IO библиотека.

2. NIO2 файлове

Имайте предвид, че в този урок ще използваме следните примерни стойности като име на входния файл и общия брой редове:

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

Java 7 представи много подобрения на съществуващите IO библиотеки и ги пакетира под NIO2:

Нека започнем с Файлове и да видим как можем да използваме неговия API, за да преброим броя на редовете:

@Test public void whenUsingNIOFiles_thenReturnTotalNumberOfLines() throws IOException { try (Stream 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 fileStream = Files.readAllLines(Paths.get(INPUT_FILE_NAME)); int noOfLines = fileStream.size(); assertEquals(NO_OF_LINES, noOfLines); }

3. NIO FileChannel

Сега нека проверим 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 Guava Files

Алтернативна библиотека на трета страна би била класът Google Guava Files . Този клас може да се използва и за преброяване на общия брой редове по начин, подобен на този, който видяхме с Files # readAllLines .

Нека започнем с добавяне на зависимостта гуава в нашия pom.xml :

 com.google.guava guava 28.0-jre 

И тогава можем да използваме readLines, за да получим списък с файлови редове:

@Test public void whenUsingGoogleGuava_thenReturnTotalNumberOfLines() throws IOException { List 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

Сега нека видим API на Apache Commons IO FileUtils , паралелно решение на Guava.

За да използваме библиотеката, трябва да включим зависимостта commons-io в pom.xml :

 commons-io commons-io 2.6 

В този момент можем да използваме 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. BufferedReader

Е, какво ще кажете за начини на старата школа? Ако не сме на 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. Скенер

И накрая, ако вече използваме скенера като част от по-голямо решение, той може да реши проблема и за нас:

@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.