我可以偷看BufferedReader吗?

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

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

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

您可以使用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 

以下代码将查看Stream中的第一个字节。 应该像你一样偷看。

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

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

例如

 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(); // ... } 
 BufferedReader br = new BufferedReader(reader); br.mark(1); int firstByte = br.read(); br.reset(); 

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

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

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

 public class PeekBufferedReader extends BufferedReader{ private Queue 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; } } }