Как читать BufferedReader быстрее

Я хочу оптимизировать этот код:

InputStream is = rp.getEntity().getContent();      

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

String text = "";
String aux = "";

while ((aux = reader.readLine()) != null) {
        text += aux;
      }

Дело в том, что я не знаю, как читать содержимое bufferedreader и копировать его в String быстрее, чем то, что я указал выше. Мне нужно проводить как можно меньше времени. Спасибо


person Cata    schedule 12.01.2011    source источник
comment
Для начала вы можете использовать StringBuilder. Это позволит избежать объединения строк. Вы также можете использовать метод чтения с большим массивом символов, но для получения оптимального размера массива потребуется некоторый сравнительный анализ.   -  person James P.    schedule 12.01.2011
comment
Вы уверены, что вам не нужно возвращать коды перевода строки, которые извлекает readLine ()?   -  person Thilo    schedule 12.01.2011
comment
LOL, потому что мне нужно проводить как можно меньше времени. Я предполагаю, что это означает, что он должен быть максимально эффективным, но я читаю его, так как хочу сделать как можно меньше работы для достижения оптимального результата.   -  person jwir3    schedule 16.10.2014
comment
См. Также: stackoverflow .com / questions / 2980805 /   -  person Christophe Roussy    schedule 09.12.2015


Ответы (6)


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

StringBuilder builder = new StringBuilder();
String aux = "";

while ((aux = reader.readLine()) != null) {
    builder.append(aux);
}

String text = builder.toString();
person Michael Borgwardt    schedule 12.01.2011
comment
Предполагается, что Java 1.5 или новее. В противном случае вы бы использовали StringBuffer. - person Greg McGowan; 12.01.2011
comment
Это хорошая идея, пока у меня не будет других альтернатив, я попробую StringBuffer. - person Cata; 12.01.2011
comment
Стоит отметить, что readLine использует символы новой строки. Этот цикл не будет очень полезным, если вы не хотите превратить весь текст в одну строку (без оператора, где раньше были символы новой строки) - person Peter Lawrey; 12.01.2011
comment
@Greg: даже Java 5 прошла дату EOSL более года назад. Пора перестать тратить умственные способности на проблемы, связанные с даже более старыми версиями. - person Michael Borgwardt; 12.01.2011
comment
Это может быть правдой, но я просто сказал, что вы предполагаете, что Cata может использовать java 1.5. - person Greg McGowan; 12.01.2011
comment
@Greg: и я утверждаю, что это предположение, которое в наши дни каждый должен делать без колебаний, если нет явной информации, противоречащей ему. - person Michael Borgwardt; 12.01.2011
comment
Учитывая, что поддержка Java 1.5 закончилась, а Java 1.6 закончилась, можно с уверенностью предположить, что ваш компилятор - это Java 1.6 или 1.7 (возможно, 1.5), но очень маловероятно, что это будет 1.4 или более ранняя версия. Я бы сказал, что использовать StringBuilder ОЧЕНЬ безопасно. - person Armand; 10.06.2013

Вы можете попробовать Apache IOUtils.toString . Вот что они делают:

StringWriter sw = new StringWriter();
char[] buffer = new char[1024 * 4];
int n = 0;
while (-1 != (n = input.read(buffer))) {
    sw.write(buffer, 0, n);
}
String text = sw.toString();
person dogbane    schedule 12.01.2011
comment
Требуется больше голосов, возможно, лучше, чем чтение построчно, особенно если строки короткие. См. stackoverflow.com / questions / 2980805 / - person Christophe Roussy; 09.12.2015

Когда BufferedReader читает из Socket, необходимо добавить bufferedReader.ready():

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

StringBuilder sb= new StringBuilder();
String line = "";

while (br.ready() && (line = br.readLine()) != null) {
    sb.append(line + "\r\n");
}

String result = sb.toString();
person michalv    schedule 18.10.2014

Однострочное решение:

String result = reader.lines().collect(joining(lineSeparator()));

Импорт:

import java.io.*;
import static java.lang.System.lineSeparator;
import static java.util.stream.Collectors.joining;
person Hykilpikonna    schedule 24.12.2018

Для этого я написал простую функцию, используя StringBuilder и цикл While с перехватом IOException внутри.

public String getString(BufferedReader bufferedReader) {
    StringBuilder stringBuilder = new StringBuilder();
    String line = null;

    do {
        try {
            if ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line).append(System.lineSeparator());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    } while (line != null);

    return stringBuilder.toString();
}
person Thach Van    schedule 07.07.2017

Вы можете использовать StringBuffer.

while ((aux = reader.readLine()) != null) {
     stringBuffer.append(aux);
}
person Community    schedule 12.01.2011
comment
@dogbane Разве StringBuffer не лучше, когда вам нужно его синхронизировать? - person 735Tesla; 02.01.2014
comment
@ 735Tesla см. Эту ссылку - person The6thSense; 21.05.2015