Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PushbackInputStream: Push back buffer is full

Why I am getting the following exception:

Exception in thread "main" java.io.IOException: Push back buffer is full
    at java.io.PushbackInputStream.unread(PushbackInputStream.java:232)
    at java.io.PushbackInputStream.unread(PushbackInputStream.java:252)
    at org.tests.io.PushBackStream_FUN.read(PushBackStream_FUN.java:32)
    at org.tests.io.PushBackStream_FUN.main(PushBackStream_FUN.java:43)

In this code:

public class PushBackStream_FUN {
    public int write(String outFile) throws Exception {
        FileOutputStream outputStream = new FileOutputStream(new File(outFile));
        String str = new String("Hello World");
        byte[] data = str.getBytes();
        outputStream.write(data);
        outputStream.close();

        return data.length;
    }

    public void read(String inFile, int ln) throws Exception {
        PushbackInputStream inputStream = new PushbackInputStream(new FileInputStream(new File(inFile)));
        byte[] data = new byte[ln];
        String str;

        // read
        inputStream.read(data);
        str = new String(data);
        System.out.println("MSG_0 = "+str);
        // unread
        inputStream.unread(data);
        // read
        inputStream.read(data);
        str = new String(data);
        System.out.println("MSG_1 = "+str);
    }

    public static void main(final String[] args) throws Exception {
        PushBackStream_FUN fun = new PushBackStream_FUN();
        String path = "aome/path/output_PushBack_FUN";
        int ln = fun.write(path);
        fun.read(path, ln);
    }
}

UPDATE

Think this is the solution. Java sources to the rescue. I have made some "experiments". It turns out that when I specify PushbackInputStream with a specified buffer size it works. The java sources tells me this:

public PushbackInputStream(InputStream in) {
        this(in, 1);
    }

public PushbackInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("size <= 0");
        }
        this.buf = new byte[size];
        this.pos = size;
    }

I think that if you use PushbackInputStream with constrcutor that uses default buffer size, you can only unread single byte. I am unreading more than single byte, thus the exception.

like image 614
alien01 Avatar asked Oct 08 '13 09:10

alien01


People also ask

What is a pushbackinputstream?

A PushbackInputStream adds functionality to another input stream, namely the ability to "push back" or "unread" one byte.

What is a pushback buffer?

For example, bytes representing the characters constituting an identifier might be terminated by a byte representing an operator character; a method whose job is to read just an identifier can read until it sees the operator and then push the operator back to be re-read. The pushback buffer.

What is pushback input in Java?

Pushback is used on an input stream to allow a byte to be read and then returned (i.e, “pushed back”) to the stream. The PushbackInputStream class implements this idea.


1 Answers

By default, PushbackInputStream only allocates enough space to be able to unread() for a single character. If you want to be able to push back more than that you must specify the capacity at construction time.

In your case it'd look something like this:

final PushbackInputStream pis = new PushbackInputStream( inputStream, ln );
like image 102
Adam Avatar answered Oct 13 '22 01:10

Adam