2

This is my code:

public int Part1(BufferedReader reader) throws IOException{
        reader.mark(0);
        int counter1 = 0;
        String z;
        while((z = reader.readLine()) != null){
            counter1 = counter1 + z.length();
        }
        reader.reset();   // this is the error line
        return counter1;
    }

It is a code to count the number of characters in a file. I have other algorithm to run in the same program which requires the BufferedReader to return to the beginning of a file. I looked at another answer on StackOverFlow and was trying to use the mark() and reset() method. However, there is a run time error:

Exception in thread "main" java.io.IOException: Stream not marked at java.io.BufferedReader.reset(Unknown Source)

What is the problem here?

AAAAAAAAAAAA
  • 37
  • 1
  • 2
  • 8

4 Answers4

3

From the docs for mark(), the parameter you pass to it is:

readAheadLimit - Limit on the number of characters that may be read while still preserving the mark. An attempt to reset the stream after reading characters up to this limit or beyond may fail. A limit value larger than the size of the input buffer will cause a new buffer to be allocated whose size is no smaller than limit. Therefore large values should be used with care.

You've passed 0; thus you've told it to invalidate the mark after 0 characters area read, which is basically immediately.

Your options:

  • You could pass the file size, but heed the warning about large values.

  • Reopen the file and start over with new Readers for each of your methods (you can either pass the filename to the methods and let them deal with it, or reopen it at a higher level and pass a shiny new BufferedReader to each method).

  • Use a FileChanneland its position methods instead.

  • Use a RandomAccessFile and its seek methods instead.

  • Switch to InputStreams instead of Readers (mind your character encodings) and, if the underlying stream is a FileInputStream you can reset to the beginning using its channel interface, e.g.:

    FileInputStream fileStream = ...; // once when you open the file
    
    // For each method (us-ascii as example):
    fileStream.getChannel().position(0);
    BufferedReader reader = new BufferedReader(new InputStreamReader(fileStream, "us-ascii"));
    // Use reader only in that method, resetting as above for each.
    
Jason C
  • 38,729
  • 14
  • 126
  • 182
2

BufferedReader is useless to move the cursor... Another superficially utils of Java (rather than Fortran and Python more auster programming langages), you must use :

RandomAccessFile randomAccessFile =new RandomAccessFile(filePath, "rw");

and use randomAccessFile.seek(0);

to go cursor in starting position, and also you prefer. See: Read lines of characters and get file position

bad_coder
  • 11,289
  • 20
  • 44
  • 72
0

Another option is to just declare another BufferedReader the next time you need one, rather than continually reset the same BufferedReader.

KyleP
  • 11
  • 2
  • 3
    If you do only this, the second `BufferedReader` will just pick up roughly where the first left off. – Jason C Mar 05 '15 at 22:46
0

I suggest not to reset a reader, because the reader can sit on another reader or stream or file that also has to be reset to work. That can lead to a lot of problems. Try to do both things at the same time or open another BufferedReader but make sure that the streams and readers underneath it are fresh as well.

When you read from a file, you might not gain anything by resetting it. Might just work like creating a new reader.

ReneS
  • 3,535
  • 2
  • 26
  • 35
  • 1
    FYI, `BufferedReader` does not call the underlying streams reset. Instead it uses the `readAheadLimit` parameter of `mark()` to resize the input buffer to be large enough at mark time, then it fills it, not using any backing stream's reset. This is why the mark is invalidated if more than `readAheadLimit` bytes have been read since the mark. The suggestion to not use a reader is still a good one, though, but for different reasons. – Jason C Mar 05 '15 at 22:48
  • Thanks for the feedback. Checked the code. The reason to avoid resetting anything are therefore mainly these two code comments: "Subsequent calls to reset() **will attempt** to reposition the stream to this point...Therefore **large values should be used with care**. " So nothing invites us to use this feature at all. – ReneS Mar 06 '15 at 16:19
  • 1
    Yes, the mark/reset mechanism as a whole seems pretty dubious to me, (and poorly supported - not even `FileReader` implements it), in general. I guess that's one reason nio went with the `SeekableByteChannel` interface approach instead. – Jason C Mar 06 '15 at 16:28