Java扫描仪可打印上一行和下一行 [英] Java Scanner to print previous and next lines
问题描述
我正在使用'java.util.Scanner'读取和扫描关键字,并希望打印遇到的关键字的前5行和后5行,以下是我的代码
I am using 'java.util.Scanner' to read and scan for keywords and want to print the previous 5 lines and next 5 lines of the encountered keyword, below is my code
ArrayList<String> keywords = new ArrayList<String>();
keywords.add("ERROR");
keywords.add("EXCEPTION");
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int count = 0;
String previousLine = null;
while(input.hasNext()){
String line = input.nextLine();
for(String keyword : keywords){
if(line.contains(keyword)){
//print prev 5 lines
system.out.println(previousLine); // this will print only last previous line ( i need last 5 previous lines)
???
//print next 5 lines
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
}
previousLine = line;
}
任何指针可以打印前5行.?
any pointers to print previous 5 lines..?
推荐答案
任何指针可以打印前5行.?
any pointers to print previous 5 lines..?
- 将其保存为
LinkedList<String>
之类的Dequeue<String>
,以实现其先进先出(FIFO)"行为. - 或者使用5个变量或5个字符串数组,将字符串从一个插槽或变量手动移至另一插槽或变量,然后打印它们.
- 如果使用Dequeue/LinkedList,请使用Dequeue的
addFirst(...)
方法将新的String添加到开头,并使用removeLast()
删除列表的最后一个String(如果其大小大于5).遍历LinkedList以获取其中包含的当前字符串. - Save them in an
Dequeue<String>
such as aLinkedList<String>
for its "First In First Out (FIFO)" behavior. - Either that or use 5 variables or an array of 5 Strings, manually move Strings from one slot or variable to another, and then print them.
- If you use Dequeue/LinkedList, use the Dequeue's
addFirst(...)
method to add a new String to the beginning andremoveLast()
to remove the list's last String (if its size is > 5). Iterate through the LinkedList to get the current Strings it contains. - 扫描仪的支票
scanner.hasNextXXX()
方法应与get方法scanner.nextXXX()
相匹配.因此,如果要呼叫nextLine()
,则应检查hasNextLine()
.否则会冒问题的风险. - 请在您的问题中尝试在此处发布真实的代码,而不是进行排序,它们将永远不会编译代码.即
system.out.println
与System.out.println
.我知道这是一件小事,但是当其他人尝试使用您的代码时,这意义重大. - 使用ArrayList的
contains(...)
方法摆脱for循环. - Your Scanner's check
scanner.hasNextXXX()
method should match the get method,scanner.nextXXX()
. So you should check forhasNextLine()
if you're going to callnextLine()
. Otherwise you risk problems. - Please try to post real code here in your questions, not sort-of, will never compile code. i.e.,
system.out.println
vsSystem.out.println
. I know it's a little thing, but it means a lot when others try to play with your code. - Use ArrayList's
contains(...)
method to get rid of that for loop.
其他建议:
例如
LinkedList<String> fivePrevLines = new LinkedList<>();
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (input.hasNextLine()) {
String line = input.nextLine();
if (keywords.contains(line)) {
System.out.println("keyword found!");
for (String prevLine : fivePrevLines) {
System.out.println(prevLine);
}
} else {
fivePrevLines.addFirst(line);
if (fivePrevLines.size() > 5) {
fivePrevLines.removeLast();
}
}
}
if (input != null) {
input.close();
}
修改
您在评论中声明:
Edit
You state in comment:
好吧,我运行了一个小型测试程序,以查看contains(...)方法是否有效...
<unreadable unformatted code>
...并且找不到此返回的关键字...!
ok i ran small test program to see if the contains(...) method works ...
<unreadable unformatted code>
... and this returned keyword not found...!
这就是您使用方式的全部. contains(...)
方法用于检查Collection是否包含另一个对象.如果您向它提供一个可能使用或可能不使用集合中的字符串之一的巨大字符串,它将不起作用,但是将对组成较大字符串的单个字符串起作用.例如:
It's all how you use it. The contains(...)
method works to check if a Collection contains another object. It won't work if you feed it a huge String that may or may not use one of the Strings in the collection, but will work on the individual Strings that comprise the larger String. For example:
ArrayList<String> temp = new ArrayList<String>();
temp.add("error");
temp.add("exception");
String s = "Internal Exception: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object";
String[] tokens = s.split("[\\s\\.:,]+");
for (String token : tokens) {
if (temp.contains(token.toLowerCase())) {
System.out.println("keyword found: " + token);
} else {
System.out.println("keyword not found: " + token);
}
}
此外,您将要避免在注释中发布代码,因为它们不保留其格式,并且不可读和不可测试.而是编辑您的原始问题并发表评论,以提醒我们进行修改.
Also, you will want to avoid posting code in comments since they don't retain their formatting and are unreadable and untestable. Instead edit your original question and post a comment to alert us to the edit.
编辑2
根据dspyz:
Edit 2
As per dspyz:
对于堆栈和队列,如果没有任何重要的功能/性能原因需要一个使用另一个,则应默认使用ArrayDeque而不是LinkedList.通常,它速度更快,占用的内存更少并且需要的垃圾收集更少.
For stacks and queues, when there isn't any significant functionality/performance reason to use one over the other, you should default to ArrayDeque rather than LinkedList. It's generally faster, takes up less memory, and requires less garbage collection.
这篇关于Java扫描仪可打印上一行和下一行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!