【问题标题】:Print last couple of lines in text file [duplicate]打印文本文件中的最后几行 [重复]
【发布时间】:2015-03-05 14:43:24
【问题描述】:

我有一个文本文件,我首先要打印它的最后 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;

【问题讨论】:

  • 我不确定为什么这已被关闭为重复,问题陈述与链接问题不同(即读取文件然后监视新行),而是首先显示最近的 6 行(OP 无法工作),然后继续监控。

标签: java loops text-files


【解决方案1】:

您必须将这些行保存到字符串数组中。并在读取整个文件后打印 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();

【讨论】:

  • 这很有效,只是想知道如果没有要读取的行,您将如何停止空打印?
  • 我只是向上帝祈祷... :-p,添加 catch 块..
  • 当 ArrayDeque 已经存在时,为什么要使用数组构建自己的环形缓冲区?此外,您没有监控添加的新行。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    1. 只需使用BufferedReader 而不是RandomAccessFile - 这就是BufferedReader 的用途
    2. 不使用数组,而是使用像ArrayDeque&lt;String&gt; 这样的FIFO 队列——这是一个完美的用例,“ringbuffer”实现完全封装在ArrayDeque

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-17
      • 2022-06-15
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 2017-01-18
      相关资源
      最近更新 更多