2010-03-25 73 views

回答

12

你可以試試 「布爾就緒()」 方法。 從Java 6 API doc:「如果緩衝區不是空的,或者底層字符流已準備好,緩衝字符流就緒。」

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

以下代碼將查看Stream中的第一個字節。應該爲你偷看。

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

但標記不返回值,所以我不能檢查真的嗎? – 2010-03-25 17:06:05

+0

但是你不想偷看,你想要返回一個值? – 2010-03-25 17:06:44

+0

是的,我想要一個int peek()。如果流中有東西,我會通過檢查返回值來得到答案,但流的狀態不會改變。 – 2010-03-26 09:09:08

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

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

很好的答案!這是Java的「偷看」。 – Pindatjuh 2010-03-25 17:17:21

+1

另請參閱:http://stackoverflow.com/a/9198381/59087 – 2014-08-11 19:23:28

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(); 
    // ... 
} 
1

你可以使用一個PushBackReader閱讀一個角色,然後「推回」。這樣,你肯定知道那裏有東西,而不會影響它的整體狀態 - 「偷看」。

1

pgmura的答案(依靠準備好()方法)很簡單,很有效。但請記住,這是因爲Sun執行該方法;這與文檔並不完全一致。如果這種行爲至關重要,我不會依賴這一點。 請看這裏http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090471 我寧願去使用PushbackReader選項。

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