Kann ich auf einem BufferedReader spähen?
-
22-09-2019 - |
Frage
Gibt es eine Möglichkeit, wenn in BufferedReader
Objekt zu überprüfen, etwas zu lesen? So etwas wie C ++ cin.peek()
. Danke.
Lösung
Sie können versuchen, die "boolean ready ()" Methode. Von der API doc Java 6: „Ein gepufferte Zeichenstrom bereit ist, wenn der Puffer nicht leer ist, oder wenn der zugrunde liegende Zeichenstrom bereit ist.“
BufferedReader r = new BufferedReader(reader);
if(r.ready())
{
r.read();
}
Andere Tipps
Sie können mit einem PushbackReader . Mit, dass Sie ein Zeichen lesen können, ungelesen es dann. Dies resultierte im Wesentlichen können Sie es zurück drücken.
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
Der folgende Code wird in dem Stream am ersten Byte aussehen. Sollte fungieren als peek für Sie.
BufferedReader bReader = new BufferedReader(inputStream);
bReader.mark(1);
int byte1 = bReader.read();
bReader.reset();
Das normale Idiom ist in einer Schleife zu überprüfen, ob BufferedReader#readLine()
nicht null
zurückgibt. Wenn Ende Strom erreicht ist (beispielsweise das Ende der Datei, socket geschlossen, usw.), dann kehrt es null
.
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 wurde), dann verwenden Sie BufferedReader#ready()
statt:
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();
könnten Sie ein PushBackReader
ein Zeichen zu lesen, und dann „zurückschieben“. Auf diese Weise können Sie sicher wissen, dass etwas da war, ohne seinen Gesamtzustand zu beeinflussen - a. „Peek“
Die Antwort von pgmura (unter Berufung auf dem fertig () -Methode) ist einfach und funktioniert. Aber bedenken Sie, dass es ist, weil Sun Durchführung des Verfahrens; die nicht wirklich mit der Dokumentation übereinstimmen. Ich würde nicht darauf verlassen, wenn dieses Verhalten kritisch ist. Sehen Sie hier http://bugs.sun.com/bugdatabase/view_bug.do? bug_id = 4090471 Ich würde lieber mit der PushbackReader Option gehen.
meine Lösung war .. BufferedReader und Verwendung Warteschlange als buf erstreckt, 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;
}
}
}