打印文本文件中的最后几行
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) 然后继续监视文件并打印新行.
我还认为您应该保持简单以更好地传达代码的意图并消除错误风险:
- 只需使用
BufferedReader
而不是 RandomAccessFile
- 这就是 BufferedReader
的作用
- 不用数组,只需使用像
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);
}
}
}
要考虑的要点:
- 对于它的价值,我会将
BufferedReader
作为参数传递进来,这样它就变得更普遍了,
- 这需要某种取消,因此它不会永远监控。
- 您也可以使用 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
我有一个文本文件,我首先要打印它的最后 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) 然后继续监视文件并打印新行.
我还认为您应该保持简单以更好地传达代码的意图并消除错误风险:
- 只需使用
BufferedReader
而不是RandomAccessFile
- 这就是BufferedReader
的作用 - 不用数组,只需使用像
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);
}
}
}
要考虑的要点:
- 对于它的价值,我会将
BufferedReader
作为参数传递进来,这样它就变得更普遍了, - 这需要某种取消,因此它不会永远监控。
- 您也可以使用 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