I would like to know what are the mark()
and reset()
methods of BufferedReader
? How do I use them? I read the Javadoc but as a beginner I was unable to understand it.

- 48,794
- 16
- 117
- 146

- 1,351
- 6
- 18
- 24
6 Answers
The mark
and reset
methods of streams provide a way to jump backwards in the stream and re-read data.
When you call mark()
on a BufferedReader
it will begin keeping data you read from that point forwards in its internal buffer. When you call reset()
it will jump back to the marked position of the stream, so the next read()
s will be satisfied by the in-memory buffer. When you read past the end of that buffer, then it will seamlessly go back to reading fresh data. BufferedInputStream
works the same way.
The int parameter to mark
tells it the maximum number of characters (for BufferedReader
) or bytes (for BufferedInputStream
) that you want to be able to go backwards. If you read too much data past the marked position, then the mark can be "invalidated", and calling reset()
will fail with an exception.
A little example:
BufferedReader r = new BufferedReader(new StringReader(
"Happy Birthday to You!\n" +
"Happy Birthday, dear " + System.getProperty("user.name") + "!"));
r.mark(1000); // save the data we are about to read
System.out.println(r.readLine()); // read the first line
r.reset(); // jump back to the marked position
r.mark(1000); // start saving the data again
System.out.println(r.readLine()); // read the first line again
System.out.println(r.readLine()); // read the second line
r.reset(); // jump back to the marked position
System.out.println(r.readLine()); // read the first line one final time
In that example, I wrapped the StringReader
in a BufferedReader
to get the readLine()
method, but StringReader
s already support mark
and reset
on their own! Streams that read from an in-memory data source usually support mark
and reset
themselves, because they already have all the data in memory so it is easy for them to read it again. Streams that read from files or pipes or network sockets do not naturally support mark
and reset
, but you can always add that feature to any stream by wrapping it in a BufferedInputStream
or BufferedReader
.
Reader::mark(int readLimit)
documentation say:
Sets a mark position in this reader. The parameter readLimit indicates how many characters can be read before the mark is invalidated. Calling reset() will reposition the reader back to the marked position if readLimit has not been surpassed.
Example:
import java.io.*;
import static java.lang.System.out;
public class App {
public static final String TEST_STR = "Line 1\nLine 2\nLine 3\nLine 4\n";
public static void main(String[] args) {
try (BufferedReader in = new BufferedReader(new StringReader(TEST_STR))) {
// first check if this Reader support mark operation
if (in.markSupported()) {
out.println(in.readLine());
in.mark(0); // mark 'Line 2'
out.println(in.readLine());
out.println(in.readLine());
in.reset(); // reset 'Line 2'
out.println(in.readLine());
in.reset(); // reset 'Line 2'
out.println(in.readLine());
in.mark(0); // mark 'Line 3'
out.println(in.readLine());
in.reset(); // reset 'Line 3'
out.println(in.readLine());
out.println(in.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output:
Line 1
Line 2
Line 3
Line 2
Line 2
Line 3
Line 3
Line 4

- 4,782
- 5
- 34
- 69
-
1How can you call `reset()`? I thought that if you `mark()` with a read limit of 0, as soon as one character is read the marker becomes invalid and it is impossible to call reset. Can you explain your answer? – snooze92 Feb 24 '14 at 14:37
-
@snooze92 Just to run this example and try to change `markLimit` argument in `mark` method. You will have the same result all time. Also see the similar examples: [1](http://goo.gl/KxU1Fy), [2](http://goo.gl/S2R3qd). I actually wanted to make questions on SO that someone gave me an explanation about it. – Anton Dozortsev Feb 24 '14 at 17:25
-
4After running more examples of my own, I understand the `mark(readAheadLimit)`/`reset()` mechanism a little bit better. Basically, the `mark` method simply marks a point in the **current buffer**, and `reset` lets you go back to that marked point. The thing is, it is not meant to mark a point in a file or stream, as it needs to increase the buffer size to keep the possibility to access the marked point. That is why one *should* use a limit that relatively smaller than the buffer size. – snooze92 Feb 25 '14 at 09:12
-
18As of *"why does the example work with a limit of 0 (or any limit actually)"* is also quite easy to explain. The default buffer size (used in both examples) is 4096. The String used for the examples is so small that it is entirely read in the first buffer as soon as the BufferedReader is created. It does not read anything more later, therefore the limit parameter is not used at all... making the example quite pointless and confusing IMHO. Changing the examples slightly to add a very small buffer size (e.g. 2 or 3) in the BufferedReader constructors will start throwing invalid mark exceptions. – snooze92 Feb 25 '14 at 09:18
-
@snooze92 Thanks for explanation. Upvoted your comments. – Anton Dozortsev Feb 25 '14 at 14:18
The mark()
marking a particular point in a stream and reset()
resets the stream to the most recent mark. These methods provide a book-marking
feature that allows you to read ahead in the stream to inspect the upcoming data.
From this documentation:
The mark() method mark a position in the input to which the stream can be "reset" by calling the reset() method. The parameter readLimit is the number of chars that can be read from the stream after setting the mark before the mark becomes invalid. For example, if mark() is called with a read limit of 10, then when 11 chars of data are read from the stream before the reset() method is called, then the mark is invalid and the stream object instance is not required to remember the mark. Note that the number of chars that can be remembered by this method can be greater than the size of the internal read buffer. It is also not dependent on the subordinate stream supporting mark/reset functionality.

- 93,659
- 19
- 148
- 186
-
can you also just use this to simply mark the beginning and go back to the beginning to re-read the buffer? for example if you wanted to read a file twice. once to get context, go back to the beginning, then read again? – fIwJlxSzApHEZIl Jan 30 '15 at 00:38
-
Reader interface does not let you return, you can just read. BufferedReader, on the other hand, creates a buffer, so you are able to return a bit when reading. And this is what those methods are for.
With mark() method you put a "marker" to a position, then you can read on. Once you realize you want to return the the marked position you use reset() for that. And from that point you read again the same values. You can use it for anything you want.

- 16,417
- 12
- 71
- 108
Imagine you have the following chars in the the BufferReader = "123456789", if you mark in the position 4 relative to the '5' char then reset your BufferReader you will end up with 12345.

- 19
- 2
-
2
-
Hey gave a proper answer. Reset just brings the pointer, which is pointing at the character to be read, to the position it has been marked at. – Umang Desai Oct 16 '13 at 12:39
Here's an example.
int bufferSize = 4;
int readLimit = 4
ByteArrayInputStream byteInputStream = new ByteArrayInputStream("123456789abcdef".getBytes());
try(BufferedInputStream bufferedInputStream = new BufferedInputStream(byteInputStream, bufferSize)) {
bufferedInputStream.mark(readLimit);
System.out.print((char) bufferedInputStream.read());//byte1
System.out.print((char) bufferedInputStream.read());//byte2
System.out.print((char) bufferedInputStream.read());//byte3
System.out.print((char) bufferedInputStream.read());//byte4
bufferedInputStream.reset();
System.out.print((char) bufferedInputStream.read());//byte5
// Using this next reset() instead of the first one will throw an exception
// bufferedInputStream.reset();
System.out.print((char) bufferedInputStream.read());
System.out.print((char) bufferedInputStream.read());
System.out.print((char) bufferedInputStream.read());
}
Output: 12341234
For the purpose of readLimit
, here's a nice reference.

- 2,635
- 6
- 31
- 47