В настоящее время я использую следующую функцию для простого HTTP GET.
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();
}
Я не вижу причин использовать BufferedReader, так как я просто собираюсь загружать все по порядку. Правильно ли я считаю, что в этом случае BufferedReader бесполезен?




Вы правы, если вы используете BufferedReader для чтения содержимого и заголовков HTTP, вам понадобится InputStreamReader, чтобы вы могли читать байт за байтом.
BufferedReader в этом сценарии иногда делает странные вещи ... особенно, когда дело доходит до чтения заголовков HTTP POST, иногда вы не сможете прочитать данные POST, если вы используете InputStreamReader, вы можете прочитать длину содержимого и прочитать это количество байтов .. .
Моя интуиция подсказывает мне, что, поскольку вы уже выполняете буферизацию с помощью массива байтов, использование BufferedReader излишне.
В этом случае я бы поступил так же, как и вы (используйте для буферизации байтовый массив, а не один из потоковых буферов).
Однако есть исключения. Одно место, где вы видите буферы (на этот раз выводимые), - это API сервлетов. Данные не записываются в базовый поток до тех пор, пока не будет вызван румянец(), что позволяет буферизовать вывод, но затем выгрузить буфер в случае возникновения ошибки и вместо этого записать страницу ошибки. Вы можете буферизовать ввод, если вам нужно сбросить поток для повторного чтения, используя отметка (число) и перезагрузить(). Например, возможно, вы бы проверили заголовок файла, прежде чем решить, в какой обработчик содержимого передать поток.
Не связано, но я думаю, вам следует переписать обработку потока. Этот шаблон лучше всего работает, чтобы избежать утечки ресурсов:
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();
}
Если вы открываете несколько потоков, вставляйте блоки try / finally.
Еще одна вещь, которую делает ваш код, - это предположение, что возвращаемый контент закодирован в наборе символов вашей виртуальной машины по умолчанию (хотя этого может быть достаточно, в зависимости от варианта использования).
Каждый вызов одного из методов read () InputStreamReader может привести к тому, что один или несколько байтов будут считаны из нижележащего входного потока байтов. Чтобы обеспечить эффективное преобразование байтов в символы, из нижележащего потока может быть прочитано больше байтов, чем необходимо для выполнения текущей операции чтения.