Я использовал следующий метод для чтения строк из ТЕКСТОВОГО ФАЙЛА, всякий раз, когда он обновляется или новые строки вставляются в текстовый файл, я должен распечатать эту новую строку

Поиск внутри этого сайта дал мне идею, но он не работает

FileReader fr = new FileReader("filename.txt");
BufferedReader reader = new BufferedReader(fr);
while (true) {
    String line = reader.readLine();
    if (line != null) {
        // Use line
    }
    else {
        thread.sleep(1000);
    }
}

Что я делаю не так?

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

0
Ahmad Abu-Hamideh 11 Окт 2016 в 09:20

4 ответа

Лучший ответ
import java.io.File;
import java.io.RandomAccessFile;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Tailer implements Runnable {
    private File file;
    private int runEvery;
    private long lastPosition = 0;
    private boolean run = true;

    public Tailer(String inputFile, int interval) {
        file = new File(inputFile);
        this.runEvery = interval;
    }

    public void stop() {
        run = false;
    }

    public void run() {
        try {
            while(run) {
                Thread.sleep(runEvery);
                long fileLength = file.length();
                if(fileLength > lastPosition) { 
                    RandomAccessFile fh = new RandomAccessFile(file, "r");
                    fh.seek(lastPosition);

                    byte c;
                    while((c = (byte)fh.read()) != -1) {
                        System.out.print((char)c);
                    }
                    lastPosition = fh.getFilePointer();
                    fh.close();
                }
            }
        }
        catch(Exception e) {
            stop();
        }
    }

    public static void main(String argv[]) {
        ExecutorService executor = Executors.newFixedThreadPool(4);
        Tailer tailer = new Tailer("test.log", 1000);
        executor.execute(tailer);
    } 
}
2
Sergey Gornostaev 11 Окт 2016 в 06:29

Единственное, о чем я могу думать, - это то, что ваш файл не сохраняется при внесении изменений, поэтому ваш код никогда не регистрирует новые строки. Кроме того, вероятно, исходный файл все еще открыт, пока вы находитесь в цикле, поэтому он никогда не открывает новый файл с изменениями. Попробуйте поместить открытый файл в цикл while и не забудьте закрыть файл.

0
DJSweetness 11 Окт 2016 в 06:41

В Linux

Файл на самом деле является индексным дескриптором. Ваш старый файл, вероятно, был удален при сохранении с помощью gedit. Например:

Сначала у вас есть filename.txt с индексом номер 10. И java его читает. Но когда вы сохраняете правку с помощью gedit. Вероятно, файл будет заменен на filename.txt с индексным номером 11. Но приложение Java все еще читает индексный дескриптор 10. Таким образом, приложение не сможет увидеть никаких изменений. Вы можете попробовать использовать "ls -i", чтобы узнать номер inode вашего файла. Посмотрите, изменилось ли оно после редактирования.

1
Ming 11 Окт 2016 в 07:50

Вы можете использовать общий класс apache org.apache.commons.io.input.Tailer.

https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/input/Tailer.html

  TailerListener listener = new MyTailerListener();
  Tailer tailer = new Tailer(file, listener, delay);

  // simple executor impl. for demo purposes
  Executor executor = new Executor() {
      public void execute(Runnable command) {
          command.run();
       }
  };

  executor.execute(tailer);

Например

class MyTailerListener extends TailerListenerAdapter {
public void handle(String line) {
  System.out.println(line);
}
}
TailerListener listener = new MyTailerListener();
Tailer tailer = Tailer.create(file, listener, 10000);
tailer.stop()
2
tomas 11 Окт 2016 в 06:34