2011-01-12 5 views
32

Я хочу, чтобы оптимизировать этот код:Как читать 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 и скопировать его в строку быстрее, чем то, что у меня есть выше. Мне нужно потратить как можно меньше времени. Спасибо

+1

Вы можете использовать StringBuilder для стартеров. Это позволит избежать конкатенации строк. Вы также можете использовать метод чтения с большим массивом символов, но для получения оптимального размера массива потребуется некоторый бенчмаркинг. –

+5

Вы уверены, что вам не нужно возвращать коды перевода строки, которые извлекает readLine()? – Thilo

+0

LOL за «Мне нужно потратить как можно меньше времени». Я предполагаю, что это означает, что он должен быть настолько эффективным, насколько это возможно, но я прочитал его как «Я хочу сделать как можно меньше работы для достижения оптимального результата». – jwir3

ответ

79

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

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

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

String text = builder.toString(); 
+4

Это предполагает, что java 1.5 или новее. В противном случае вы будете использовать StringBuffer. –

+0

Это хорошая идея, пока у меня нет других альтернатив, я попробую StringBuffer. – Cata

+9

Стоит отметить, что readLine потребляет новые строки. Этот цикл не будет очень полезен, если вы не захотите превратить весь текст в одну строку (без сператора, где раньше были строки) –

-1

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

while ((aux = reader.readLine()) != null) { 
    stringBuffer.append(aux); 
} 
+6

-1 предпочитают StringBuilder над StringBuffer. – dogbane

+3

@dogbane Не лучше StringBuffer, когда вам нужно синхронизировать его? – 735Tesla

+0

@ 735Tesla см. Это [ссылка] (http://stackoverflow.com/questions/355089/stringbuilder-and-stringbuffer) – The6thSense

22

Вы можете попробовать 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(); 
+1

Нужно больше upvotes, вероятно, лучше, чем чтение по строкам, особенно если строки коротки. См. Http://stackoverflow.com/questions/2980805/string-assembly-by-stringbuilder-vs-stringwriter-and-printwriter –

5

Когда BufferedReader читает из сокета, необходимо добавить 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(); 
+0

Не читает ли эти данные, а затем проверяет, готова ли она? – mjaggard

+1

Правильно, теперь все правильно. – michalv

0

Я написал простую функцию, чтобы сделать это с помощью StringBuilder и во время цикла с ловлей 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(); 
}