Posso espiar um leitor de buffers?
-
22-09-2019 - |
Pergunta
Existe uma maneira de verificar se BufferedReader
Objeto é algo para ler? Algo como C ++ cin.peek()
. Obrigado.
Solução
Você pode experimentar o método "boolean pronto ()". Do documento da API Java 6: "Um fluxo de caracteres em buffer está pronto se o buffer não estiver vazio ou se o fluxo de caracteres subjacente estiver pronto".
BufferedReader r = new BufferedReader(reader);
if(r.ready())
{
r.read();
}
Outras dicas
Você pode usar um PushbackReader. Usando isso, você pode ler um personagem e não lida. Isso essencialmente permite que você o empurre de volta.
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
O código a seguir analisará o primeiro byte no fluxo. Deve atuar como uma espiada para você.
BufferedReader bReader = new BufferedReader(inputStream);
bReader.mark(1);
int byte1 = bReader.read();
bReader.reset();
O idioma normal deve verificar um loop se BufferedReader#readLine()
não retorna null
. Se o final do fluxo for atingido (por exemplo, final do arquivo, soquete fechado, etc.), ele retorna null
.
Por exemplo
BufferedReader reader = new BufferedReader(someReaderSource);
String line = null;
while ((line = reader.readLine()) != null) {
// ...
}
Se você não quiser ler em linhas (que é a maneira como a principal razão de BufferedReader
foi escolhido), depois use BufferedReader#ready()
em vez de:
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();
Você poderia usar um PushBackReader
para ler um personagem e depois "empurrá -lo de volta". Dessa forma, você sabe com certeza que algo estava lá, sem afetar seu estado geral - uma "espiada".
A resposta de Pgmura (confiando no pronto() método) é simples e funciona. Mas lembre -se de que é porque a implementação do método pelo Sun; que realmente não concorda com a documentação. Eu não confiaria nisso, se esse comportamento for crítico. Veja aqui http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4090471Prefiro ir com a opção PushbackReader.
Minha solução foi .. estendendo -se o BufferErader e use a fila como BUF, você pode usar o método Peek na fila.
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;
}
}
}