-1

我正在开发一些必须读取日志文件的程序,我认为我在其中构建了一个智能机制,结果代码甚至无法编译......

我犯了一个很大的设计缺陷:如何修复它?

public class Reader implements Runnable {
    private volatile boolean isReading;

    private final File file;

    public Reader(final File file) {
        this.file = file;
    }

    @Override
    public void run() {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException ex) {
            throw new IllegalStateException("bf4logreader.Reader.run: File has not been found. file = " + file);
        }
        while (isReading) {
            String line = null;
            try {
                line = reader.readLine();
            } catch (IOException ex) {
                throw new IllegalStateException("bf4logreader.Reader.run: Something went wrong when reading file. file = " + file);
            }
            if (line == null) {
                //No new lines
                long startSleepTime = System.currentTimeMillis();
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException ex) {
                    if (isReading) {
                        //Not supposed to be interrupted
                        Thread.sleep(System.currentTimeMillis() - startSleepTime);
                    }
                    else {
                        try {
                            //Needs to shutdown
                            reader.close();
                        } catch (IOException ex1) {
                            Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex1);
                        }
                    }
                }
            }
            else {
                //Process new lines
                System.out.println("Line: " + line);
            }
        }
    }

    public void shutdown() {
        isReading = false;
    }
}

我认为很聪明,如果线程被不适当地中断,它仍然必须休眠的时间让线程处于休眠状态。但是我当然不能在这个派系中这样做,因为它需要再次处理Thread.sleep's 。InterrruptedException

我认为它需要转换为某个while循环,但我该怎么做呢?

编辑:对不起,我忘了把这个程序背后的想法。但我想实时监控一个日志文件,所以它永远不会停止读取该文件,除非我用关闭消息表示。

4

3 回答 3

1

请尝试以下代码:

try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
  String line;
  while (running) {
    while ((line = reader.readLine()) != null) {
      System.out.println(line);
    }
    Thread.sleep(1000); // end of file has been reached, wait a second for more data
  }
} catch (FileNotFoundException ex) {
  // ...
} catch (IOException ex) {
  // ...
} catch (InterruptedException ex) {
}

try (ressource) catch成语将确保阅读器在任何情况下都正确关闭,因此您不必担心。

readLine()函数将自动阻塞(暂停当前执行)直到数据可用,因此不需要任何睡眠或类似操作。如果它返回 null,则到达文件末尾,因此您可以退出。

如果抛出任何 InterruptedException,线程将正确终止。这个异常总是作为线程尽快退出工作的信号被抛出,所以你永远不应该忽略它。

通过抛出一个完全不同的异常来处理像 IOException 这样的常见异常通常是错误的,因为它隐藏了错误的实际原因。而是首先处理向您抛出的错误。
此外,IllegalStateException 是通常不会在任何地方捕获的 RuntimeException,从而导致您的整个代码立即终止。你可能不想要那个。

于 2013-11-15T11:36:32.733 回答
0

检查这是否有帮助

 RandomAccessFile in = new RandomAccessFile("/home/hduser/Documents/Sample.txt", "r");
        String line;
        long length = 0;//used to check the file length
        while (true) {
            if(in.length()<length){//new condition to reset position if file length is reduced 
                in.seek(0);
            }
            if ((line = in.readLine()) != null) {
                System.out.println(line);
                length = in.length();
            } else {
                Thread.sleep(2000);
            }
        }
于 2013-11-15T11:48:31.590 回答
-1

您可能不喜欢这个答案,但请尝试使用 shell 而不是编写 Java 程序。我自己是 Java 开发人员,但如果我听说与日志有关,我会尝试使用 unix/linux shell。编写 Java 代码将花费您 20 倍以上的时间,您可能无法找到所有边缘情况,并且很难更改任何内容,因为您的程序将是 200 行代码而不是 5 行代码。

还有你的代码。它远非完美,尽管您担心这不是编译。在这里,您有您的类 Sir,它将编译甚至工作。有点:

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Reader implements Runnable {
  private volatile boolean isReading;

  private final File file;

  public Reader(final File file) {
    this.file = file;
  }

  @Override
  public void run() {
    BufferedReader reader;
    try {
      reader = new BufferedReader(new FileReader(file));
    } catch (FileNotFoundException ex) {
      throw new IllegalStateException("bf4logreader.Reader.run: File has not been found. file = " + file);
    }
    isReading = true;
    while (isReading) {
      String line;
      try {
        line = reader.readLine();
      } catch (IOException ex) {
        throw new IllegalStateException("bf4logreader.Reader.run: Something went wrong when reading file. file = " + file);
      }
      if (line == null) {
        //No new lines
        long startSleepTime = System.currentTimeMillis();
        try {
          Thread.sleep(500);
        } catch (InterruptedException ex) {
          if (isReading) {
            //Not supposed to be interrupted
            try {
              Thread.sleep(System.currentTimeMillis() - startSleepTime);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
          else {
            try {
              //Needs to shutdown
              reader.close();
            } catch (IOException ex1) {
              Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex1);
            }
          }
        }
      }
      else {
        //Process new lines
        System.out.println("Line: " + line);
      }
    }
  }

  public void shutdown() {
    isReading = false;
  }


  public static void main(String[] args) throws InterruptedException {

    Reader reader = new Reader(new File("res/integers.txt"));
    new Thread(reader).start();
    Thread.sleep(1000);
    reader.shutdown();
  }
}
于 2013-11-15T11:53:01.997 回答