Як дізнатися кількість рядків у файлі Java
Знайдіть кількість рядків у файлі за допомогою Java
У цьому посібнику ми дізнаємося , як знайти кількість рядків у файлі за допомогою 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
(StreamString>
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
ListString>
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 .
Давайте почнемо з додавання залежності guava до нашого pom.xml :
dependency>
groupId>com.google.guavagroupId>
artifactId>guavaartifactId>
version>31.0.1-jreversion>
dependency>
І потім ми можемо використовувати readLines для отримання списку рядків файлу:
@Test
public
void
whenUsingGoogleGuava_thenReturnTotalNumberOfLines()
throws
IOException
ListString>
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-iogroupId>
artifactId>commons-ioartifactId>
version>2.11.0version>
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.
- 1. Огляд
- 2. Файли NIO2
- 3. Файловий канал NIO
- 4. Файли Гуави Google
- 5. Apache Commons IO FileUtils
- 6. Буферизований читач
- 7. LineNumberReader
- 8. Сканер
- 9. Висновок
Підрахунок кількості рядків у текстовому файлі (java)
Нижче наведено приклад того, як я підраховую кількість рядків у текстовому файлі. Просто цікаво, чи є інші способи це зробити?
while(inputFile.hasNext()) < a++; inputFile.nextLine(); >inputFile.close();
Я намагаюся ввести дані до масиву, я не хочу читати текстовий файл двічі.
Будь-яка допомога/поради цінуються.
4 відповіді
Якщо ви використовуєте версію Java 7 або вище, ви можете безпосередньо прочитати всі рядки в список за допомогою методу readAllLines. Це буде легко
List lines = Files.readAllLines(Paths.get(fileName), Charset.defaultCharset());
Тоді розмір списку поверне вам кількість рядків у файлі
int noOfLines = lines.size();
Якщо ви використовуєте Java 8, ви можете використовувати потоки:
long count = Files.lines(Paths.get(filename)).count();
Це буде мати гарну продуктивність і дійсно виразно.
Нестача (порівняно з відповіддю Тусити Тіліна Дайаратен) полягає в тому, що у вас є лише кількість рядків. Якщо ви також хочете мати рядки у списку, ви можете зробити (досі використовуючи потоки Java 8) :
// First, read the lines List lines = Files.lines(Paths.get(filename)).collect(Collectors.toList()); // Then get the line count long count = lines.size();
Якщо ви просто хочете додати дані до масиву, то я додаю нові значення до масиву. Якщо кількість даних, які ви читаєте, не велика, і вам не потрібно робити це часто, це має бути нормально. Я використовую щось подібне до цього, як показано в цій відповіді: Читання звичайного текстового файлу в Java
BufferedReader fileReader = New BufferedReader(New FileReader("path/to/file.txt")); try < StringBuilder sb = New StringBuilder(); String line = br.readLine(); while (line! = null) <sb.append (line); sb.append(System.lineSeparator()); line = br.readLine(); >String everything = sb.toString(); > finally
Якщо ви читаєте числами, рядки можуть бути перетворені на числа, наприклад, для цілих чисел intValue = Integer.parseInt(text)
У мене немає достатньої репутації, щоб коментувати, але відповідь @superbob майже ідеальна, дійсно, ви повинні переконатися, що передаєте Charset.defaultCharset() як другий параметр, наприклад:
Files.lines(file.toPath(), Charset.defaultCharset()).count()
Це відбувається тому, що Files.lines використовує UTF-8 за промовчанням, а потім використовує, оскільки це не за замовчуванням, система UTF-8 може виробляти java.nio.charset.MalformedInputException.
Підрахунок кількості рядків у текстовому файлі
У багатьох редакторах під час роботи з текстовим документом ви можете бачити, скільки всього рядків міститься у цьому файлі. Рядки між собою поділяються символом перекладу рядка, який у кожній операційній системі (Windows, Unix, Mac) свій.
Давайте розберемося, як швидко підрахувати кількість рядків у текстовому файлі незалежно від ОС, в якому виконується наш код. Більше того, текстовий файл може бути як завгодно великим, тому ми будемо використовувати буферизацію потоку, щоб не витратити всю доступну оперативну пам'ять.
Припустимо, наш метод приймає на вхід абсолютний шлях до цільового файлу, а повертає кількість рядків у вигляді цілісного типу long. Розглянемо дві реалізації.
Варіант з LineNumberReader
public static long getLineCountByReader(String fileName) throws IOException <
try ( var lnr = new LineNumberReader( new FileReader(fileName))) <
while (lnr.readLine()! = null);
return lnr.getLineNumber();
>
>
Спочатку ми в конструкції try-with-resources послідовно створюємо два Reader'a, обертаючи один до одного:
- FileReader – для роботи із файлом.
- LineNumberReader - Власне, для підрахунку кількості рядків.
Буферизація потоку у явному вигляді непотрібен, т.к. LineNumberReader вже успадковується від BufferedReader.
Всі перелічені рідери підтримують інтерфейс AutoCloseable та конструкція try-with-resources гарантує нам, що після виходу з цього блоку вони будуть закриті.
Потім у циклі викликаємо у LineNumberReader метод readLine(). Оскільки жодних додаткових дій нам робити не треба, тіло циклу буде порожнім. Після виходу із циклу метод getLineNumber() повертає кількість рядків у файлі.
На мій погляд, це найбільш «читана» реалізація, але нижче ми розглянемо трохи швидшу версію. А поки що можемо викликати наш метод:
public static void main(String[] args) throws IOException <
System.out.println( "Lines count: " + getLineCountByReader( "/home/user/very-large-file.txt" ));
>
Навіть для текстового файлу на десятки мегабайт підрахунок кількості рядків займає менше секунди.
Варіант з інкрементом
Наш метод можна трохи прискорити, відмовившись від LineNumberReader. Натомість будемо підраховувати рядки за допомогою звичайного інкременту.
public static long getLineCountByIncrement(String fileName) throws IOException <
var lines = 0L;
try ( var reader = new BufferedReader( new FileReader(fileName))) <
while (reader.readLine() != null ) <
lines++;
>
return lines;
>
>
Тут ми так само в блоці try створюємо FileReader і BufferedReaderщоб після закінчення вони були гарантовано закриті. Після цього в циклі на кожній ітерації також викликаємо метод readLine(). На цей раз тіло циклу у нас не порожнє, в ньому ми збільшуємо змінну lines на 1. Така реалізація швидше за попередню приблизно на 10%.
Подібні статті
- Як дізнатися точну кількість лайків у ВК
- Як дізнатися максимальну кількість потоків процесора
- Як дізнатися кількість акцій у лоті
- Що означає сон про велику кількість риби
- Що дає велику кількість підходів
- Скільки становить кількість шийних хребців у страусів
- Чи можна дізнатися результати ЄДІ раніше
- Чи можна дізнатися з ким листується людина у ВК