0

I have a text file that I am reading. It has chunks that I would want to remove. Is there a way I can say If the reader comes across a String "STATEMENT OF ACCOUNT" it skips reading the 10 lines before that Statement. This is the code I am currently using which is reading everything from the Text file.

  for(int i = 0; i < filenames.length; i++){
   FileInputStream fstemp = new FileInputStream("C:/Temporary/" + filenames[i]); 
   FileOutputStream fos = new FileOutputStream("C:/Statements/" + filenames[i]);  
   DataInputStream in1 = new DataInputStream(fstemp);
   UniqueLineReader brtemp = new UniqueLineReader(new InputStreamReader(in1));
   BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
   String strLine;
   while((strLine = brtemp.readLine()) != null){
     bw.write(strLine);
     bw.newLine();
     bw.flush();

   }


    }
Mat
  • 202,337
  • 40
  • 393
  • 406
Stanley Mungai
  • 4,044
  • 30
  • 100
  • 168

3 Answers3

4

I'm assuming you actually want to skip the 10 lines after the "STATEMENT OF ACCOUNT" line. In which case, you want something like this:

int linesToSkip = 0;
String strLine;
while((strLine = brtemp.readLine()) != null) {
  if (linesToSkip > 0) {
    linesToSkip--;
    continue;
  }
  if (strLine.equals("STATEMENT OF ACCOUNT")) {
    linesToSkip = 10;
    continue;
  }
  bw.write(strLine);
  bw.newLine();
  bw.flush();
}

If you really want to somehow obliterate the previous ten lines, then you'd need to delay output (e.g. saving it in a cyclical buffer) until ten lines later, just in case you see "STATEMENT OF ACCOUNT" in a few lines' time.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Won't that skip the 10 lines of text following "STATEMENT OF ACCOUNT", instead of the 10 lines of text preceding it? – Sean Reilly Feb 08 '12 at 14:23
  • You made the same mistake I did, he wants to skip the *previously* read 10 lines, not the 10 lines to come. – Timeout Feb 08 '12 at 14:24
  • @SeanReilly: Yes - see the text before and after the code. I strongly suspect this is *actually* what the OP wants, but he expressed it badly. – Jon Skeet Feb 08 '12 at 14:25
  • @b1naryj: I've explicitly stated that I believe the OP actually wants to skip the 10 lines after the trigger line - and given a suggested plan for if he really does want to skip the 10 lines before the trigger line. – Jon Skeet Feb 08 '12 at 14:26
  • @jon: yeah, I missed that when I looked at your answer the first time. Sorry. – Sean Reilly Feb 08 '12 at 14:36
1

It sounds like you need to maintain a buffer of 10 lines so that when you encounter your special line, you can abandon the contents. Until you see it, you add every line to one end and only output from the other end when the buffer is full. The answers to this question recommend a Queue or CircularFifoBuffer for this type of situation.

Here's an untested code sample using a CircularFifoBuffer:

for (int i = 0; i < filenames.length; i++) {
    FileInputStream fstemp = new FileInputStream("C:/Temporary/" + filenames[i]);
    FileOutputStream fos = new FileOutputStream("C:/Statements/" + filenames[i]);
    DataInputStream in1 = new DataInputStream(fstemp);
    UniqueLineReader brtemp = new UniqueLineReader(new InputStreamReader(in1));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
    Buffer ringbuf = new CircularFifoBuffer(10);
    String strLine;
    while ((strLine = brtemp.readLine()) != null) {
        if (strLine.equals("STATEMENT OF ACCOUNT")) {
            ringbuf.clear();
        }

        ringbuf.add(strLine);

        if (ringbuf.isFull()) {
            bw.write(ringbuf.remove());
            bw.newLine();
            bw.flush();
        }
    }

    for (Object item : ringbuf) {
        bw.write(item);
        bw.newLine();
        bw.flush();
    }
}
Community
  • 1
  • 1
Mike Partridge
  • 5,128
  • 8
  • 35
  • 47
1

You can do it by buffering the preceding 10 lines in a queue:

Queue<String> queue = new LinkedList<String>();
String strLine;
while ((strLine = brtemp.readLine()) != null {
    queue.add(strLine);
    if (strLine.equals("STATEMENT OF ACCOUNT")) {
        queue.clear();
        continue;
    }

    while (queue.size() >= 10) {
        bw.write(queue.remove());
        bw.newLine();
    }
}
while (!queue.isEmpty()) {
    bw.write(queue.remove());
    bw.newLine();
}
bw.flush();
Sean Reilly
  • 21,526
  • 4
  • 48
  • 62