# PushbackReader

The *Java* *PushbackReader* class, `java.io.PushbackReader`, is intended to be used when you parse data from a [Reader](https://jenkov.com/tutorials/java-io/reader.html). Sometimes you need to read ahead a few characters to see what is coming, before you can determine how to interpret the current character. The Java `PushbackReader` allows you to do that. Well, actually it allows you to push back the read characters into the `Reader`. These characters will then be read again the next time you call `read()`.

The Java `PushbackReader` works much like the [`PushbackInputStream`](https://jenkov.com/tutorials/java-io/pushbackinputstream.html) except that the `PushbackReader` works on characters, whereas the `PushbackInputStream` works on bytes.

### PushbackReader Example

Here is a simple `PushbackReader` example:

```
PushbackReader pushbackReader =
    new PushbackReader(new FileReader("c:\\data\\input.txt"));

int data = pushbackReader.read();

pushbackReader.unread(data);
```

The call to `read()` reads a character from the `PushbackReader` just like from any other `Reader`. The call to `unread()` pushes a character back into the `PushbackReader`. The next time `read()` is called the pushed back characters will be read first. If you push back multiple characters into the `PushbackReader`, the latest pushed back character will be returned first from the `read()` method, just like with a stack.

### Create a PushbackReader

To use a Java `PushbackReader` you must first create a `PushbackReader` instance. You create a `PushbackReader` using standard object instantiation - using the `new` operator. To the `PushbackReader` constructor you must pass a [Java Reader](https://jenkov.com/tutorials/java-io/reader.html) from which the `PushbackReader` will read its characters. Here is an example of creating a Java `PushbackReader`:

```
PushbackReader pushbackReader =
    new PushbackReader(new FileReader("c:\\data\\input.txt"));
```

This example passes a [Java FileReader](https://jenkov.com/tutorials/java-io/filereader.html) to the `PushbackReader` constructor. This will make the `PushbackReader` read its characters from this `FileReader`.

### Setting the Push Back Limit of a PushbackReader

You can set the number of characters you should be able to unread in the constructor of the `PushbackReader`. Here is how to set the pushback limit using the `PushbackReader` constructor:

```
int pushbackLimit = 8;
PushbackReader reader = new PushbackReader(
                                new FileReader("c:\\data\\input.txt"),
                                pushbackLimit);
```

This example sets an internal buffer of 8 characters in the `PushbackReader`. That means you can unread at most 8 characters at a time, before reading them again.

### Read Characters

You read characters from a Java `PushbackReader` just like you do from a Java `Reader` - because `PushbackReader` is a Java `Reader` subclass. In other words, you use its `read()` method which is inherited from the `Reader` class. Here is an example of reading characters from a Java `PushbackReader` via its `read()` method:

```
int aChar = pushbackReader.read();
while(aChar != -1) {
    System.out.println((char) aChar);
    aChar = pushbackReader.read();
}
```

The `read()` returns an `int` which you will have to cast to a `char` yourself, as shown in the example above. When there are no characters available in the `PushbackReader` the `read()` method will return the `int` value -1.

### Push Back Characters

To push a character back into a Java `PushbackReader` you must call its `unread()` method. Here is an example of pushing back a character into a `PushbackReader` :

```
int aChar = pushbackReader.read();

pushbackReader.unread(aChar);

aChar = pushbackReader.read(); // reads character pushed back
```

This example reads a character from a `PushbackReader`, then pushes it back into the `PushbackReader`, and then reads that character from the `PushbackReader` again.

### Closing a PushbackReader

When you are finished reading characters from the `PushbackReader` you should remember to close it. Closing a `PushbackReader` will also close the `Reader` instance from which the `PushbackReader` is reading.

Closing a `PushbackReader` is done by calling its `close()` method. Here is how closing a `PushbackReader` looks:

```
pushbackReader.close();
```

You can also use the [try-with-resources](https://jenkov.com/java-exception-handling/try-with-resources.html) construct introduced in Java 7. Here is how to use and close a `PushbackReader` looks with the try-with-resources construct:

```
Reader reader = new FileReader("data/data.bin");

try(PushbackReader pushbackReader =
    new PushbackReader(reader)){

    int data = pushbackReader.read();
    while(data != -1) {
        System.out.print((char) data);
        data = pushbackReader.read();
    }
}
```

Notice how there is no longer any explicit `close()` method call. The try-with-resources construct takes care of that.

Notice also that the first `FileReader` instance is not created inside the try-with-resources block. That means that the try-with-resources block will not automatically close this `FileReader` instance. However, when the `PushbackReader` is closed it will also close the `Reader` instance it reads from, so the `FileReader` instance will get closed when the `PushbackReader` is closed.

### Parsing Example

At the end of this Java `PushbackReader` tutorial, lets see a slightly more elaborate example of how you can use the `PushbackReader` when parsing a stream of characters. This example samples the first character of the next "token" to be read from a `PushbackReader` to determine the type of the next token, then pushes back the character for the corresponding tokenizer to read. The example is a bit "constructed" for the occasion, meaning in a real parser you might do things a bit differently. However, the example serves mostly to show how the `PushbackReader` can be used in a real parsing example, not as a text book example of writing great parsers.

```
public class TextTokenizer {
    protected PushbackReader pushbackReader =  null;

    public TextTokenizer(Reader reader) {
        this.pushbackReader = new PushbackReader(reader);
    }

    public String nextToken() {
        int firstChar = this.pushbackReader.read();
        this.pushbackReader.unread(firstChar);

        if(((char)firstChar) == '"') {
           return readDoubleQuotedToken();
        }
        if((char)firstChar) == '\'') {
           return readSingleQuotedToken();
        }
        return readSingleWordToken();
    }

    protected String readDoubleQuotedToken() { ... }

    protected String readSingleQuotedToken() { ... }

    protected String readSingleWordToken()   { ... }
}
```

The interesting part of this example is the `nextToken()` method. This method first reads a character from the `PushbackReader` into a variable, then pushes the read character back into the `PushbackReader`. This way the `nextToken()` method can "sample" the first character of the next token, and based on that decide what kind of token it is, and what read method to call for that kind of token.

Note, that for the single and double quoted tokens it would actually not be necessary to push the character back into the `PushbackReader`, because the quotes themselves are typically not included as part of the token. For the `readSingleTokenWord()` however, it is necessary, as the character read is the first character of the token's value.

The implementations of the `readDoubleQuotedToken()`, `readSingleQuotedToken()` and `readSingleWordToken()` have been left out to keep the example short. Just imagine they read a token enclosed by double quotes ("), single quotes (') or a token which ends with a non-word character (e.g. a space, tab, line break etc.).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://amartyushov.gitbook.io/tech/programming-languages/java/io-nio/java-io-input-parsing/pushbackreader.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
