我可以偷看BufferedReader吗?

时间:2010-03-25 17:00:02

标签: java bufferedreader peek

有没有办法检查BufferedReader对象中是否有东西要读?像C ++ cin.peek()之类的东西。感谢。

8 个答案:

答案 0 :(得分:33)

您可以使用PushbackReader。使用它你可以读取一个字符,然后将其读取。这基本上允许你推回它。

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

答案 1 :(得分:14)

您可以尝试“boolean ready()”方法。 从Java 6 API doc:“如果缓冲区不为空,或者基础字符流已准备就绪,则缓冲字符流已准备好。”

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

答案 2 :(得分:12)

以下代码将查看Stream中的第一个字节。应该为你看一眼。

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

答案 3 :(得分:4)

正常的习惯用法是在BufferedReader#readLine()没有返回null时检查循环。如果到达流的末尾(例如文件结束,套接字关闭等),则返回null

E.g。

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

如果你不想读行(这是选择BufferedReader的主要原因),那么请改用BufferedReader#ready()

BufferedReader reader = new BufferedReader(someReaderSource);
while (reader.ready()) {
    int data = reader.read();
    // ...
}

答案 4 :(得分:2)

BufferedReader br = new BufferedReader(reader);
br.mark(1);
int firstByte = br.read();
br.reset();

答案 5 :(得分:1)

您可以使用PushBackReader来阅读字符,然后“将其推回”。这样你就可以确定某些东西存在,而不会影响它的整体状态 - 一个“偷看”。

答案 6 :(得分:1)

pgmura的答案(依赖于 ready ()方法)很简单且有效。 但请记住,这是因为Sun实施的方法;这与文档并不完全一致。如果这种行为很关键,我不会依赖它。 见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090471 我宁愿选择PushbackReader选项。

答案 7 :(得分:0)

我的解决方案是..扩展BufferedReader并使用队列作为buf,然后你可以在队列中使用peek方法。

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;
        }
    }
}