2011-01-12 22 views
32

Quiero optimizar este código:Como leer más rápido BufferedReader

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

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

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

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

El caso es que no sé cómo leer el contenido de la BufferedReader y copiarlo en una cadena más rápido que lo que tengo encima. Necesito pasar el menor tiempo posible. Gracias

+1

Puede utilizar un StringBuilder para empezar. Evitará la concatenación de cadenas. También puede usar el método de lectura con una matriz de caracteres grande, pero obtener el tamaño de matriz óptimo requerirá una evaluación comparativa. –

+5

¿Está seguro de que no necesita volver a colocar los códigos de salto de línea que se extrae readLine()? – Thilo

+0

LOL para "Necesito pasar el menor tiempo posible". Supongo que esto significa que debe ser lo más eficiente posible, pero lo leí como "Quiero hacer el menor trabajo posible para lograr el resultado óptimo". – jwir3

Respuesta

79

mediante concatenación de cadenas en un bucle es la clásico asesino rendimiento (porque las cadenas son inmutables, toda la cadena cada vez más grande, se copia para cada una concatenación). Hacer esto en su lugar:

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

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

String text = builder.toString(); 
+4

Eso supone que Java 1.5 o posterior. De lo contrario, sería StringBuffer lo que usarías. –

+0

Es una buena idea, hasta que no tenga otras alternativas, probaré StringBuffer. – Cata

+9

Vale la pena señalar que readLine consume nuevas líneas. Este bucle no será muy útil a menos que desee convertir todo el texto en una línea (sin sperator donde solían estar las nuevas líneas) –

-1

Puede utilizar StringBuffer

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

-1 prefieren StringBuilder sobre StringBuffer. – dogbane

+3

@dogbane ¿No es mejor StringBuffer cuando necesita sincronizarlo? – 735Tesla

+0

@ 735Tesla ver este [enlace] (http://stackoverflow.com/questions/355089/stringbuilder-and-stringbuffer) – The6thSense

22

Usted puede intentar Apache IOUtils.toString. Esto es lo que hacen:

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

Necesita más votos positivos, probablemente mejor que leer línea por línea, especialmente si las líneas son cortas. Ver http://stackoverflow.com/questions/2980805/string-assembly-by-stringbuilder-vs-stringwriter-and-printwriter –

5

Cuando BufferedReader lee de zócalo, es necesario añadir 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

¿No lee esto la información y luego verifica si está lista? – mjaggard

+1

Correcto, ahora es correcto. – michalv

0

escribí una función simple de hacer esto utilizando StringBuilder y While con la captura de IOException dentro .

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(); 
}