Могу ли я заглянуть в BufferedReader?
Есть ли способ проверить, есть ли в объекте BufferedReader
что-то для чтения? Что-то вроде С++ cin.peek()
. Спасибо.
Ответы
Ответ 1
Вы можете попробовать "boolean ready()" метод.
Из документа Java 6 API: "Буферизованный поток символов готов, если буфер не пуст, или если базовый поток символов готов."
BufferedReader r = new BufferedReader(reader);
if(r.ready())
{
r.read();
}
Ответ 2
Вы можете использовать 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
Ответ 3
Следующий код будет смотреть на первый байт в потоке. Должен действовать как заглянуть за вас.
BufferedReader bReader = new BufferedReader(inputStream);
bReader.mark(1);
int byte1 = bReader.read();
bReader.reset();
Ответ 4
Нормальная идиома - проверить цикл, если BufferedReader#readLine()
не возвращает null
. Если конец потока достигнут (например, конец файла, сокет закрыт и т.д.), Он возвращает null
.
например.
BufferedReader reader = new BufferedReader(someReaderSource);
String line = null;
while ((line = reader.readLine()) != null) {
// ...
}
Если вы не хотите читать строки (что, кстати, основная причина a BufferedReader
выбрана), используйте BufferedReader#ready()
вместо:
BufferedReader reader = new BufferedReader(someReaderSource);
while (reader.ready()) {
int data = reader.read();
// ...
}
Ответ 5
BufferedReader br = new BufferedReader(reader);
br.mark(1);
int firstByte = br.read();
br.reset();
Ответ 6
Вы можете использовать PushBackReader
, чтобы прочитать символ, а затем "отбросить его". Таким образом, вы точно знаете, что что-то там, не влияя на его общее состояние - "заглянуть".
Ответ 7
Ответ pgmura (полагающийся на метод ready()) прост и работает.
Но имейте в виду, что это связано с внедрением Sun метода; что на самом деле не согласуется с документацией. Я бы не стал полагаться на это, если это поведение имеет решающее значение.
См. Здесь http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090471
Я предпочел бы воспользоваться опцией PushbackReader.
Ответ 8
мое решение было... расширение 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;
}
}
}