Here is my code:
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class MarkAndResetDemo {
public static void main(String[] args) {
String s = "Today is Sunday!";
byte buf[] = s.getBytes();
System.out.println("s: "+s);
ByteArrayInputStream in = new ByteArrayInputStream(buf);
int c, count = 0;
try(BufferedInputStream f = new BufferedInputStream(in, 4)) {//Line 1
while((c=f.read()) != -1) {
System.out.print((char)c);
count++;
if(count==3) f.mark(2); //Line 2
if(count==8) f.reset(); //Line 3
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
When the count is set as 8 in Line 3, output is:
s: Today is Sunday!
Today isjava.io.IOException: Resetting to invalid mark
When the count is set as 7 in Line 3, output is:
s: Today is Sunday!
Today iay is Sunday!
So my question is why "invalid mark" exception is not appearing when count is 7 in Line 3 since more than 2 bytes have been read since the mark(int i) was last called? It seems that internal buffer of BufferedInputStream is being filled one byte at a time unless mark(int i) is invalidated.
I know that BufferedInputStream will read chunk of data of size equal to its internal buffer from the inputstream (and here the buffer size is 4). So after 4 iterations of while loop the internal buffer of BufferedInputStream should contain the next 4 bytes from the byte array(buf[] which means the characters 'y', ' ', 'i', 's' in byte encoded form). Also the mark(2) in Line 2 will place a hook on the current position(the next byte to be read in the inputstream) while mark(int i) is called.
When the mark is set, the buffer contains 'Toda' and the marked character is 'a'. When we need to refill the buffer to print 'y', the first 3 characters are discarded (because they aren't needed for the mark), three new characters are read, and the buffer now contains 'ay i'. After printing 7 characters 'ay ' we haven't needed to refill the buffer, so reset can still reset to the 'a'.
If you want to understand things like this, put some breakpoints in the JDK classes.