Чтение новых данных из постоянно обновляемого файла на Java - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть файл журнала, который постоянно пополняется новыми строками данных.Мне нужно получить новые добавленные данные в Java, как только они написаны.На данный момент мое решение:

public static void readNonStop(String filename, boolean goToEnd, FileReadCallback readCallback) {
    if(readCallback == null) {
        return;
    }
    try {
        BufferedReader br = new BufferedReader(new FileReader(filename));
        try {
            String line = br.readLine();
            int lineNumber = 0;

            if(goToEnd) {
                while(br.readLine() != null) {}
            }

            while (true) {
                if(line != null) {
                    readCallback.onRead(lineNumber++, line);
                } else {
                    Thread.sleep(1);
                }
                line = br.readLine();
            }
        } finally {
            br.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Но у меня есть ощущение, что должен быть лучший путь.Мне не нравится идея постоянного цикла выполнения с «спящим» внутри, и я предпочитаю какой-то подход, управляемый событиями.

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

Как правильно сделать это для этой ситуации?

Заранее спасибо!

1 Ответ

0 голосов
/ 27 декабря 2018

Файлы не предназначены для обмена сообщениями.Даже при использовании TCP over loopback задержка может составлять 10 - 30 микросекунд.Без изменения формата файла ваше решение, вероятно, будет самым быстрым.

ПРИМЕЧАНИЕ: вам не нужно спать в течение целой миллисекунды.Вы можете использовать Thread.yield() или LockSupport.parkNanos(100_000);. Для более сложной стратегии у вас может быть класс, такой как LongPauser , который настраивается обратно.

Кстати, я реализовал решение, чтобы написать/ читать файлы с низкой задержкой, называемой Chronicle Queue.Это имеет задержки в микросекунды, использующие двоичный формат для скорости.

ПРИМЕЧАНИЕ: Вы можете просто до конца пропустить все байты available(), когда вы открываете файл как FileInputStream.Это может привести к неполной строке в зависимости от того, как работает ваша буферизация.

...