Existe um motivo para usar BufferedReader em vez de InputStreamReader ao ler todos os caracteres?
-
09-06-2019 - |
Pergunta
Atualmente uso a seguinte função para fazer um HTTP GET simples.
public static String download(String url) throws java.io.IOException {
java.io.InputStream s = null;
java.io.InputStreamReader r = null;
//java.io.BufferedReader b = null;
StringBuilder content = new StringBuilder();
try {
s = (java.io.InputStream)new URL(url).getContent();
r = new java.io.InputStreamReader(s);
//b = new java.io.BufferedReader(r);
char[] buffer = new char[4*1024];
int n = 0;
while (n >= 0) {
n = r.read(buffer, 0, buffer.length);
if (n > 0) {
content.append(buffer, 0, n);
}
}
}
finally {
//if (b != null) b.close();
if (r != null) r.close();
if (s != null) s.close();
}
return content.toString();
}
Não vejo razão para usar o BufferedReader
já que vou baixar tudo em sequência.Estou certo em pensar que não adianta BufferedReader
nesse caso?
Solução
Nesse caso, eu faria o que você está fazendo (use uma matriz de bytes para buffer e não um dos buffers de fluxo).
Existem exceções, no entanto.Um lugar onde você vê buffers (saída desta vez) é na API do servlet.Os dados não são gravados no fluxo subjacente até rubor() é chamado, permitindo que você armazene a saída em buffer, mas depois despeje o buffer se ocorrer um erro e escreva uma página de erro.Você pode armazenar a entrada em buffer se precisar redefinir o fluxo para releitura usando marca (int) e reiniciar().Por exemplo, talvez você inspecione o cabeçalho do arquivo antes de decidir para qual manipulador de conteúdo passar o fluxo.
Não relacionado, mas acho que você deveria reescrever o tratamento do stream.Este padrão funciona melhor para evitar vazamentos de recursos:
InputStream stream = new FileInputStream("in");
try { //no operations between open stream and try block
//work
} finally { //do nothing but close this one stream in the finally
stream.close();
}
Se você estiver abrindo vários fluxos, aninhe os blocos try/finally.
Outra coisa que seu código está fazendo é presumir que o conteúdo retornado está codificado no conjunto de caracteres padrão da sua VM (embora isso possa ser adequado, dependendo do caso de uso).
Outras dicas
Você está correto, se usar BufferedReader para ler conteúdo e cabeçalhos HTTP, você desejará InputStreamReader para poder ler byte por byte.
BufferedReader neste cenário às vezes faz coisas estranhas ... especialmente quando se trata de ler cabeçalhos HTTP POST, às vezes você não conseguirá ler os dados POST, se usar o InputStreamReader você pode ler o comprimento do conteúdo e ler tantos bytes. .
Cada invocação de um de um Leitor de entradaStreamOs métodos read() de podem fazer com que um ou mais bytes sejam lidos do fluxo de entrada de bytes subjacente.Para permitir a conversão eficiente de bytes em caracteres, mais bytes podem ser lidos antecipadamente do fluxo subjacente do que o necessário para satisfazer a operação de leitura atual.
Meu instinto me diz que, como você já está executando o buffer usando a matriz de bytes, é redundante usar o BufferedReader.