Reputation: 166
I am reading a log file line by line using BufferedReader. If a line is match an exact pattern i also acquire previous lines. This line number is entered by user. For example pattern is "ERROR" and line number 3 so i will store ERROR line and previous 3 lines.
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");
}
}
Any suggestions will be appreciated.
Upvotes: 2
Views: 109
Reputation: 2068
As I said in my comment you can keep track of the last how-many-ever lines the user asked for at each step. So after reading a line of the log that does not contain "ERROR" you would add it to your list of remembered lines and if at that point that list of remembered lines is longer than the number of lines the user asked for, throw away the oldest entry in it.
So in code it would look something like this (you can just use a LinkedList
for your data structure) :
// 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();
}
}
}
Upvotes: 1
Reputation: 31658
You will have to keep the last n lines read saved so that you can always display them when encountering an error line.
The hard part is creating a data structure to keep track of the last n lines for you.
Perhaps you can use something like the answer to this question Looking for a circular fixed size array-based deque
So your code would look like this
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);
}
Upvotes: 2