2010-03-25 16 views
17

Gibt es eine Möglichkeit zu überprüfen, ob in BufferedReader Objekt etwas zu lesen ist? Etwas wie C++ cin.peek(). Vielen Dank.Kann ich einen BufferedReader sehen?

+1

Ich habe das Gefühl, dass Mehrdeutigkeit gibt es in C++ 's Peek und Java Peek. "Prüfe, ob etwas zu lesen ist" stimmt nicht mit "Peek" in Java überein. – BalusC

Antwort

12

können Sie versuchen, die "boolean ready()" Methode. Aus dem Java 6-API-Dokument: "Ein gepufferter Zeichenstrom ist bereit, wenn der Puffer nicht leer ist oder wenn der zugrunde liegende Zeichenstrom bereit ist."

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

Der folgende Code zeigt das erste Byte im Stream an. Sollte als ein Blick für Sie fungieren.

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

Aber Marke gibt keinen Wert zurück, also kann ich nicht wirklich überprüfen? –

+0

Aber dann wollen Sie nicht einen Blick, möchten Sie einen Wert zurückgeben? –

+0

Ja möchte ich einen int peek(). Wenn etwas in einem Stream ist, werde ich die Antwort darauf erhalten, indem ich den Rückgabewert überprüfe, aber der Status des Streams ändert sich nicht. –

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

Sie können eine PushbackReader verwenden. Mit diesem können Sie ein Zeichen lesen und es dann lesen. Dies ermöglicht es Ihnen im Wesentlichen, es zurück zu schieben.

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

Gute Antwort! Dies ist der Java "Peek". – Pindatjuh

+1

Siehe auch: http://stackoverflow.com/a/9198381/59087 –

4

Die normale Idiom ist in einer Schleife zu überprüfen, ob BufferedReader#readLine() nicht null zurückgibt. Wenn das Ende des Streams erreicht ist (z. B. Dateiende, Socket geschlossen, usw.), wird null zurückgegeben.

z.

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

Wenn Sie nicht in den Zeilen lesen möchten (was übrigens ist der Hauptgrund, ein BufferedReader gewählt worden), dann verwenden Sie BufferedReader#ready() statt:

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

Sie einen PushBackReader verwenden könnte um ein Zeichen zu lesen und dann "zurück zu drücken". So weißt du sicher, dass etwas da war, ohne seinen Gesamtzustand zu beeinflussen - ein "Blick".

1

Die Antwort von pgmura (basierend auf der bereit() -Methode) ist einfach und funktioniert. Aber bedenken Sie, dass es wegen Suns Implementierung der Methode ist; was nicht wirklich mit der Dokumentation übereinstimmt. Ich würde mich nicht darauf verlassen, wenn dieses Verhalten kritisch ist. Siehe hier http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090471 Ich würde lieber mit der PushbackReader-Option gehen.

0

meine Lösung war .. erweitern BufferedReader und verwenden Warteschlange als buf, dann können Sie Peek-Methode in der Warteschlange verwenden.

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