1. Обзор
Этот урок продемонстрирует, как эффективно читать большие файлы в Java. Java - вернуться к основам.
2. Читать в памяти
Стандартный способ прочитать линии файлов - читать в памяти. Как гуава, так и apachecommonio предоставляют методы для быстрого чтения файлов линий следующим образом:
Files.readLines(new File(path), Charsets.UTF_8);
FileUtils.readLines(new File(path));
Проблема с этим методом заключается в том, что все строки файла хранятся в памяти, и когда файл достаточно большой, он быстро приведет к тому, что программа выдвигает исключение OutfmemoryError.
Например: прочитайте файл около 1G:
@Testpublic void deadusingguava_whenitertingafile_thenworks () бросает ioexception {String path = ... files.readlines (новый файл (path), charsets.utf_8);}Этот метод занимает лишь небольшое количество памяти в начале: (он потребляет около 0 МБ памяти)
[Main] Info org.baeldung.java.corejavaiounittest - Тотальная память: 128 МБ [Main] Info org.baeldung.java.corejavaiounittest - Бесплатная память: 116 МБ
Однако, когда все файлы читаются в память, мы, наконец, можем увидеть (примерно 2 ГБ памяти потребляется):
[Main] Информация org.baeldung.java.corejavaiounittest - Тотальная память: 2666 МБ [Main] Info org.baeldung.java.corejavaiounittest - Бесплатная память: 490 МБ
Это означает, что этот процесс потребляет около 2,1 ГБ памяти - причина проста: теперь все строки файла хранятся в памяти.
Размещение всего содержимого файла в памяти быстро исчерпает доступную память - независимо от того, насколько велика фактическая доступная память, это очевидно.
Кроме того, нам обычно не нужно помещать все строки файла одновременно одновременно - вместо этого нам просто нужно пройти каждую строку файла, затем выполнять соответствующую обработку и выбрасывать ее после обработки. Итак, это именно то, что мы собираемся сделать - перевернуть через ряды, вместо того, чтобы помещать все ряды в память.
3. Поток файла
Теперь давайте посмотрим на это решение - мы будем использовать класс java.util.scanner для сканирования содержимого файла и прочитать его непрерывно строить по строке:
FileInputStream inputStream = null; scanner sc = null; try {inputStream = new FileInputStream (path); SC = новый сканер (inputStream, "UTF-8"); while (sc.hasnextline ()) {string line = sc.nextline (); // System.out.println (Line); } // Обратите внимание, что сканер подавляет исключения, если (sc.ioexception ()! = null) {throw sc.ioexception (); }} наконец {if (inputStream! = null) {inputStream.close (); } if (sc! = null) {sc.close (); }}Это решение пройдет все строки в файле - позволяя обрабатывать каждую строку, не сохраняя на него ссылку. Во всяком случае, они не хранились в памяти: (было потреблено около 150 МБ памяти)
[main] infoorg.baeldung.java.corejavaiounittest-totalmemory: 763mb
[main] infoorg.baeldung.java.corejavaiounittest-freememory: 605mb
4. Apachecommonsio Stream
Вы также можете использовать библиотеку Commonisio для ее реализации, используя пользовательский линейный линейный, предоставленный библиотекой:
LineIterator it = fileUtils.lineiterator (theFile, "utf-8"); try {while (it.hasnext ()) {String line = it.nextline (); // Сделайте что -нибудь с Line}} наконец {lineiterator.closequietly (it);}Поскольку весь файл не хранится в памяти, это приводит к довольно консервативному потреблению памяти: (примерно 150 МБ памяти потребляется)
[Main] Infoo.B.Java.corejavaiointegrationtest-totalmemory: 752mb
[Main] Infoo.B.Java.corejavaiointegrationtest-Freememory: 564MB
5. Заключение
В этой короткой статье описывается, как обрабатывать большие файлы без повторного чтения и запуска памяти - это дает полезное решение для обработки больших файлов.
Все эти примеры реализованы, и фрагменты кода доступны в моем проекте Github - это проект на основе Eclipse, поэтому его следует легко импортировать и запустить.
Выше приведено все содержание этой статьи о эффективном чтении Java больших файлов. Я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!