Can I peek on a BufferedReader?

喜你入骨 提交于 2019-11-30 11:11:58

You can try the "boolean ready()" method. From the Java 6 API doc: "A buffered character stream is ready if the buffer is not empty, or if the underlying character stream is ready."

BufferedReader r = new BufferedReader(reader);
if(r.ready())
{
   r.read();
}
Gavin H

You can use a PushbackReader. Using that you can read a character, then unread it. This essentially allows you to push it back.

PushbackReader pr = new PushbackReader(reader);
char c = (char)pr.read();
// do something to look at c
pr.unread((int)c); //pushes the character back into the buffer

The following code will look at the first byte in the Stream. Should act as a peek for you.

BufferedReader bReader = new BufferedReader(inputStream);
bReader.mark(1);
int byte1 = bReader.read();
bReader.reset();

The normal idiom is to check in a loop if BufferedReader#readLine() doesn't return null. If end of stream is reached (e.g. end of file, socket closed, etc), then it returns null.

E.g.

BufferedReader reader = new BufferedReader(someReaderSource);
String line = null;
while ((line = reader.readLine()) != null) {
    // ...
}

If you don't want to read in lines (which is by the way the major reason a BufferedReader is been chosen), then use BufferedReader#ready() instead:

BufferedReader reader = new BufferedReader(someReaderSource);
while (reader.ready()) {
    int data = reader.read();
    // ...
}
BufferedReader br = new BufferedReader(reader);
br.mark(1);
int firstByte = br.read();
br.reset();

You could use a PushBackReader to read a character, and then "push it back". That way you know for sure that something was there, without affecting its overall state - a "peek".

The answer from pgmura (relying on the ready() method) is simple and works. But bear in mind that it's because Sun's implementation of the method; which does not really agree with the documentation. I would not rely on that, if this behaviour is critical. See here http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090471 I'd rather go with the PushbackReader option.

my solution was.. extending BufferedReader and use queue as buf, then you can use peek method in queue.

public class PeekBufferedReader extends BufferedReader{

    private Queue<String>       buf;
    private int                 bufSize;

    public PeekBufferedReader(Reader reader, int bufSize) throws IOException {
        super(reader);
        this.bufSize = bufSize;
        buf = Queues.newArrayBlockingQueue(bufSize);
    }

    /**
     * readAheadLimit is set to 1048576. Line which has length over readAheadLimit 
     * will cause IOException.
     * @throws IOException 
     **/
    //public String peekLine() throws IOException {
    //  super.mark(1048576);
    //  String peekedLine = super.readLine();
    //  super.reset();
    //  return peekedLine;
    //}

    /**
     * This method can be implemented by mark and reset methods. But performance of 
     * this implementation is better ( about 2times) than using mark and reset  
     **/
    public String peekLine() throws IOException {
        if (buf.isEmpty()) {
            while (buf.size() < bufSize) {
                String readLine = super.readLine();
                if (readLine == null) {
                    break;
                } else {
                    buf.add(readLine);
                }
            }
        } else {
            return buf.peek();
        }
        if (buf.isEmpty()) {
            return null;
        } else {
            return buf.peek();
        }
    }

    public String readLine() throws IOException {
        if (buf.isEmpty()) {
            while (buf.size() < bufSize) {
                String readLine = super.readLine();
                if (readLine == null) {
                    break;
                } else {
                    buf.add(readLine);
                }
            }
        } else {
            return buf.poll();
        }
        if (buf.isEmpty()) {
            return null;
        } else {
            return buf.poll();
        }
    }
    public boolean isEmpty() throws IOException {
        if (buf.isEmpty()) {
            while (buf.size() < bufSize) {
                String readLine = super.readLine();
                if (readLine == null) {
                    break;
                } else {
                    buf.add(readLine);
                }
            }
        } else {
            return false;
        }
        if (buf.isEmpty()) {
            return true;
        } else {
            return false;
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!