如何通过读取bufferedreader来获取前一行的可变数量

时间:2013-12-27 15:46:36

标签: java file bufferedreader

我正在使用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");   
     }
 }

任何建议都将受到赞赏。

2 个答案:

答案 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();
        }
    }
}