Есть ли причина использовать BufferedReader поверх InputStreamReader при чтении всех символов? - PullRequest
5 голосов
/ 28 августа 2008

В настоящее время я использую следующую функцию для простого 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 бесполезен?

Ответы [ 4 ]

4 голосов
/ 28 августа 2008

В этом случае я бы поступил так же, как вы (используйте байтовый массив для буферизации, а не один из потоковых буферов).

Хотя есть исключения. Единственное место, где вы видите буферы (на этот раз выводите), - это API сервлета. Данные не записываются в базовый поток до тех пор, пока не будет вызвана flush () , что позволит вам буферизовать вывод, но затем выгрузить буфер в случае возникновения ошибки и вместо этого записать страницу ошибки. Вы можете буферизовать ввод, если вам нужно сбросить поток для перечитывания, используя mark (int) и reset () . Например, может быть, вы захотите проверить заголовок файла, прежде чем принять решение о том, какой обработчик содержимого будет передавать поток.

Не имеет отношения, но я думаю, что вам следует переписать обработку вашего потока. Этот шаблон лучше всего работает, чтобы избежать утечек ресурсов:

    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.

Еще одна вещь, которую ваш код делает, предполагает, что возвращаемый контент закодирован в наборе символов по умолчанию вашей виртуальной машины (хотя это может быть достаточно, в зависимости от варианта использования).

1 голос
/ 18 января 2010

Каждый вызов одного из InputStreamReader методов read () может привести к тому, что один или несколько байтов будут считаны из базового байтового потока ввода. Чтобы обеспечить эффективное преобразование байтов в символы, из базового потока может быть прочитано больше байтов, чем необходимо для выполнения текущей операции чтения.

1 голос
/ 28 августа 2008

Вы правы, если вы используете BufferedReader для чтения содержимого HTTP и заголовков, вам понадобится InputStreamReader, чтобы вы могли читать байт за байтом.

BufferedReader в этом сценарии иногда делает странные вещи ... особенно, когда речь идет о чтении заголовков HTTP POST, иногда вы не сможете прочитать данные POST, если вы используете InputStreamReader, вы можете прочитать длину содержимого и прочитать так много байт ...

0 голосов
/ 28 августа 2008

Моя интуиция говорит мне, что, поскольку вы уже выполняете буферизацию с использованием байтового массива, использование BufferedReader излишне.

...