2

I use PushbackInputStream to look ahead the next byte in a stream (bufferedIn which is a BufferedInputStream) because I want to mark() before some value, and later to rewind prior to it using reset().

// Wrap input stream into a push back stream
PushbackInputStream pbBufferedIn = new PushbackInputStream(bufferedIn, 20);
boolean markDone = false; // Flag for mark
boolean resetDone = false; // Flag for reset

// Read each byte in the stream (some twice)
for (int i = pbBufferedIn.read(); i != -1; i = pbBufferedIn.read()) {
    // Convert to byte
    byte b = (byte) i;
    // Check for marking before value -1
    if (!markDone) {
        if (b == -1) {
            // Push character back
            pbBufferedIn.unread(i);
            // Mark for later rewind
            pbBufferedIn.mark(20);
            markDone = true;
            System.out.print("[mark] ");                    
            // Re-read
            pbBufferedIn.read();
        }
    }

    // Print the current byte
    System.out.print(b + " ");

    // Check for rewind after value 1
    if (markDone && !resetDone && b == 1) {
        pbBufferedIn.reset(); // <------ mark/reset not supported!
        resetDone = true;
        System.out.print("[reset] ");
    }
}

Ironically PushbackInputStream doesn't support mark/reset... on the other hand BufferedInputStream that supports mark/reset don't have a push-back mechanism... How can I do?

mins
  • 6,478
  • 12
  • 56
  • 75

3 Answers3

2

Mark/reset is sort of the equivalent to pushback. PushbackInputStream is for when your input stream does not support buffering. So you read, then push that back into the stream.

With BufferedInputStream you just mark(10), read the 10 bytes with read(10) then call reset(). Now your stream is back 10 bytes and you can read it again, so you have effectively picked at it.

Edy Bourne
  • 5,679
  • 13
  • 53
  • 101
2

BufferedInputStream ( stream replay ):

  • you mark now (start creating a buffer) so that you can replay later (at some buffer position).
  • Also you cannot replace the buffered content with something else.

PushbackInputStream ( stream corrected-replay ):

  • there is always a buffer available to which you can reset (at some buffer position)
  • You can provide the replay contents to that buffer.

Below I provide the corresponding examples with length-1-buffers for simplicity:

PushbackInputStream pbis = 
new PushbackInputStream(new ByteArrayInputStream(new byte[]{'a','b','c'}));
System.out.println((char)pbis.read());
System.out.println((char)pbis.read());
pbis.unread('x'); //pushback after read
System.out.println((char)pbis.read());        
System.out.println((char)pbis.read());        

BufferedInputStream bis = 
new BufferedInputStream(new ByteArrayInputStream(new byte[]{'a','b','c'}));
System.out.println((char)bis.read());
bis.mark(1);//mark before read
System.out.println((char)bis.read());
bis.reset();//reset after read
System.out.println((char)bis.read());        
System.out.println((char)bis.read());

Result:

a
b
x   //correction
c

a
b
b   //replay
c
Marinos An
  • 9,481
  • 6
  • 63
  • 96
0

If you have mark and reset you don't need pushback as well.

user207421
  • 305,947
  • 44
  • 307
  • 483