我正在使用BufferedReader逐行读取日志文件。如果一条线与精确模式匹配,我也会获得前一条线。该行号由用户输入。例如,模式是" ERROR"和第3行,所以我将存储ERROR行和前3行。
FileInputStream fInStream = new FileInputStream(fileBase);
br = new BufferedReader(new InputStreamReader(fInStream));
while ((line = br.readLine()) != null) {
if(line.contains("ERROR")){
//here, i should write previous 3 lines and then ERROR line
bw.write(line + "\r\n");
}
}
任何建议都将受到赞赏。
答案 0 :(得分:2)
您必须保留最后n行读取保存,以便在遇到错误行时始终显示它们。
困难的部分是创建一个数据结构来跟踪最后n行。
也许您可以使用类似问题的答案Looking for a circular fixed size array-based deque
所以你的代码看起来像这样
Ring ring = new Ring(n);
while ((line = br.readLine()) != null) {
if(line.contains("ERROR")){
//note no checking to see if there are n lines
//currently stored in Ring maybe have to make a size() method
// and check that
for(int i=0; i<n; i++){
bw.write(ring.get(i) + "\r\n");
}
bw.write(line + "\r\n");
}
//add line to Ring here
ring.push(line);
}
答案 1 :(得分:1)
正如我在评论中所说,您可以跟踪用户在每一步所要求的最后多少行。因此,在读取不包含“ERROR”的日志行之后,您会将其添加到记忆行列表中,如果此时记住的行列表长于用户要求的行数,则丢弃最古老的条目。
所以在代码中它看起来像这样(你可以使用LinkedList
作为数据结构):
// number of lines to print before the ERROR
int numContextLines = // user input
...
Deque<String> contextLines = new LinkedList<String>();
while ((line = br.readLine()) != null) {
if(line.contains("ERROR")){
// print out all of the context lines
for (String contextLine : contextLines) {
bw.write(contextLine + "\r\n");
}
bw.write(line + "\r\n");
} else {
// this is not an ERROR message so store it in our list of
// context lines that we can print when we find an ERROR
contextLines.addFirst(line);
// if this list has gotten too long then throw away the oldest entry in it
if (contextLines.size() > numContextLines) {
contextLines.removeLast();
}
}
}