Как эффективно отслеживать изменения (и, что наиболее важно, чтение) действительно больших файлов в Java

#java #file #file-io #bigdata

#java #файл #file-io #bigdata

Вопрос:

У меня есть большой файл журнала в текстовой форме, созданный сторонним приложением. К сожалению, мой файл имеет размер 150 МБ, у других могут быть файлы еще большего размера, в зависимости от дня, когда они начали регистрироваться. Поскольку файл создается сторонним приложением, я не могу его каким-либо образом изменить (например, удалить часть его самого старого содержимого).

Что я хочу сделать, так это отслеживать размер файла и получать уведомления о добавлении новой строки (таким образом, размер файла изменяется), а затем прочитать эту строку (это будет последняя строка).

Я знаю, когда я хочу отслеживать изменения, это не обязательно должно быть постоянное обновление, но когда пользователь сворачивает приложение в трее. По сути, я хочу уведомлять пользователя об изменениях в состоянии приложения, когда он их не видит.

Теперь я отслеживаю различия в размере файла, используя

 File file = new File("filepath"); 
file.length();
 

Насколько я понимаю, это не загружает файл в память, поэтому это не так сильно снижает производительность.

Если я прав, каков наиболее эффективный способ чтения last line этого файла?

Замените эффективность на «как можно более низкое снижение производительности». Я не возражаю против задержки в 2 или 3 секунды между фактическим событием, регистрируемым в файле, и уведомлением пользователя.

Ответ №1:

Вы можете использовать DirectoryWatcher для получения уведомлений об изменении каталога или файла. Вы можете использовать RandomAccessFile для перехода в любую позицию, например, где вы читаете до последнего байта, и считываете байты с этой точки. Вы можете использовать устаревший метод readLine(), если вы особенно заботитесь о кодировании.

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

Причина, по которой вы хотите скопировать сначала, заключается в том, что вы можете получить неполные строки или даже неполные многобайтовые символы, которые Bufferedreader обрабатывает не особенно хорошо.