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

时间:2015-01-07 16:27:08

标签: java loops text-files

我有一个文本文件,我首先想要打印最后6行,然后检测何时添加了新行,以便它将继续使用最近的活动更新屏幕。我的想法是,我正在尝试显示我的程序中最近的六笔交易。

我目前遇到的问题是它在文本文件中保持打印第一行(而不是最后一行),当我希望它是另一种方式时。

以下是我的示例代码:

  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;

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

您必须将行保存到String 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();

答案 2 :(得分:1)

虽然还有其他4个答案,但我认为无论如何都不能解决问题:(1)打印最后6行和(2)然后继续监控文件并打印新行

我还认为你应该保持简单,以便更好地传达代码的意图并消除bug风险:

  1. 只使用BufferedReader而不是RandomAccessFile - 这就是BufferedReader的用途
  2. 而不是使用数组只需使用像ArrayDeque<String>这样的FIFO队列 - 这是一个完美的用例,而“ringbuffer”实现完全封装在ArrayDeque
  3. 执行所有这些操作的准系统实现类似于:

    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而不是轮询和休眠您的线程,但该代码将比适合此答案的代码更复杂。
    4. 上面的代码给出了以下输出

      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