打印文本文件中的最后几行

Print last couple of lines in text file

我有一个文本文件,我首先要打印它的最后 6 行,然后检测何时添加了新行,以便它会使用最近 activity 不断更新屏幕。这个想法是我试图显示我的程序中最近进行的六笔交易。

我目前遇到的问题是它一直打印文本文件中的前六行(不是最后六行),而我希望它以相反的方式显示。

这是我的示例代码:

  BufferedReader in = new BufferedReader(new FileReader("transaction-list.txt"));

  System.out.println();
  System.out.println("SIX MOST RECENT TRANSACTIONS:");
  System.out.println();

  String line;

  for (int i=0; i<6;i++){
    line=in.readLine();
    System.out.println(line);
  }

  in.close();

}catch (IOException e){
  e.printStackTrace();
}
break;

您当前的逻辑只读取前 6 行并打印它,基本上您可以将所有行读取到列表中并删除不需要的那些行。检查以下 post: How to read last 5 lines of a .txt file into java

您必须将行保存到字符串数组中。阅读整个文件后,只需打印 Array。只记得从哪里开始读取保存的数组..

    BufferedReader in = new BufferedReader(new FileReader("transaction-list.txt"));
    System.out.println();
    System.out.println("SIX MOST RECENT TRANSACTIONS:");
    System.out.println();
    String[] last6 = new String[6];
    int count=0;
    while(in.ready()){
        last6[count++%6]=in.readLine();
    }
    for (int i=0; i<6;i++){
        System.out.println(last6[(i+count)%6]);
    }
    in.close();

虽然还有 4 个其他答案,但我认为没有任何解决办法同时说明您的观点:(1) 打印最后 6 行和 (2) 然后继续监视文件并打印新行.

我还认为您应该保持简单以更好地传达代码的意图并消除错误风险:

  1. 只需使用 BufferedReader 而不是 RandomAccessFile - 这就是 BufferedReader 的作用
  2. 不用数组,只需使用像 ArrayDeque<String> 这样的 FIFO 队列——这是一个完美的用例,"ringbuffer" 实现完全封装在 ArrayDeque[=40 中=]

完成所有这些的准系统实现类似于:

public static void MonitorFile(String filePath)
    throws FileNotFoundException, IOException, InterruptedException
{
    //  Used for demo only: count lines after init to exit function after n new lines
    int newLineCount = 0;

    //  constants
    final int INITIAL_LINE_LIMIT = 6;
    final int POLLING_INTERVAL = 1000;

    //  file readers
    FileReader file = new FileReader(filePath);
    BufferedReader fr = new BufferedReader(file);

    //  read-and-monitor loop
    boolean initialising = true;
    Queue<String> lineBuffer = new ArrayDeque<String>(INITIAL_LINE_LIMIT);
    int lineCount = 0;
    while (true) {
        String line= fr.readLine();
        if (line != null)
        {
            if (initialising) { // buffer
                lineBuffer.add(line);
                if (++lineCount > INITIAL_LINE_LIMIT) lineBuffer.remove();
            }
            else { // print
                System.out.printf("%d  %s%n", ++lineCount, line);
                newLineCount++;
            }
        }
        else
        {
            //  No more lines, so dump buffer and/or start monitoring
            if (initialising)
            {
                initialising = false;
                // reset the line numbers for printing
                lineCount = Math.max(0, lineCount - INITIAL_LINE_LIMIT);
                // print out the buffered lines
                while((line = lineBuffer.poll()) != null)
                    System.out.printf("%d  %s%n", ++lineCount, line);

                System.out.println("finished pre-loading file: now monitoring changes");
            }
            //  Wait and try and read again.
            if (newLineCount > 2) break; // demo only: terminate after 2 new lines
            else Thread.sleep(POLLING_INTERVAL);
        }
    }
}

要考虑的要点:

  1. 对于它的价值,我会将 BufferedReader 作为参数传递进来,这样它就变得更普遍了,
  2. 这需要某种取消,因此它不会永远监控。
  3. 您也可以使用 file change monitoring,而不是轮询和休眠您的线程,但该代码会比适合此答案的代码更复杂。

以上代码输出如下

2  test line b
3  test line c
4  test line d
5  test line e
6  test line f
7  test line g
finished pre-loading file: now monitoring changes
8  test line h
9  test line i
10  test line j
11  test line k