Эффективный метод для чтения строк строк из файла - PullRequest
4 голосов
/ 06 февраля 2011

Предполагая, что у меня есть файл журнала 15 ГБ, и я хотел бы перебрать \ n завершенные строки из этого файла. Какие стандартные библиотеки Java / сторонние поставщики предоставляют чистый интерфейс для этой операции.

Обратите внимание, что я ищу решение на основе NIO, предпочтительно с использованием метода доступа к файлу Memory Mapped, как показано в этом вопросе Как создать строку Java из содержимого файла? будет было бы идеальным решением, если бы он не загружал весь байтовый буфер в память перед возвратом нового экземпляра буфера String (). Этот подход не работает в этом случае из-за размера ввода.

Спасибо,
Максим.

Ответы [ 3 ]

4 голосов
/ 06 февраля 2011

Рассматривали ли вы использование BufferedReader?Из документации:

Считывает текст из потока ввода символов, буферизует символы для обеспечения эффективного чтения символов, массивов и строк .

Он имеет чистый интерфейс для получения \n -определенных строк (BufferedReader.readLine()) и должен быть достаточно эффективным, поскольку он буферизован.

3 голосов
/ 06 февраля 2011

ИМХО вам не нужен ни один NIO для этой задачи. Используйте обычный BufferedReader:

BufferedReader reader = new BufferedReader(new FileReader("myfile.log"));

Тогда пользователь reader.readLine().

2 голосов
/ 06 февраля 2011

Он не основан на NIO, но я бы взглянул на метод Guava CharStreams.readLines (InputSupplier, LineProcessor) . Он делает то, что вы хотите, я бы сказал:

File file = ...
Foo result = CharStreams.readLines(Files.newReaderSupplier(file, Charsets.UTF_8),
    new LineProcessor<Foo>() {
      public boolean processLine(String line) {
        // do stuff for this line
        return true; // or false if you want to stop processing here
      }

      public Foo getResult() {
        return result; // if you create some result when processing the lines
      }
    });

При этом используется обратный вызов, чтобы вы могли последовательно обрабатывать каждую строку в файле. Он не загружает следующую строку в память, пока вы не закончите обработку текущей. Если вы не хотите создавать какой-либо один объект результата при чтении строк, вы можете просто использовать LineProcessor<Void> и иметь getResult() return null.

...