2008-08-28 13 views
5

Actualmente uso la siguiente función para hacer un simple HTTP GET.¿Hay alguna razón para usar BufferedReader sobre InputStreamReader al leer todos los caracteres?

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

veo ninguna razón para utilizar el BufferedReader ya que sólo voy a descargar todo en secuencia. ¿Estoy en lo cierto al pensar que no sirve de nada el BufferedReader en este caso?

Respuesta

4

En este caso, yo haría lo que está haciendo (utilice una matriz de bytes para el almacenamiento en búfer y no uno de los búferes de flujo).

Existen excepciones, sin embargo. Un lugar donde ve los almacenamientos intermedios (salida esta vez) está en la API de servlet. Los datos no se escriben en la secuencia subyacente hasta que se llama flush(), lo que le permite almacenar en el búfer pero luego volcar el búfer si se produce un error y escribir una página de error en su lugar. Es posible que la entrada de almacenamiento intermedio sea necesaria si es necesario reiniciar la transmisión para volver a leer utilizando mark (int) y reset(). Por ejemplo, tal vez inspeccione el encabezado del archivo antes de decidir a qué controlador de contenido pasar la secuencia.

No relacionado, pero creo que debería volver a escribir el manejo de su secuencia. Este patrón funciona mejor para evitar fugas de recursos:

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

Si está abriendo varias secuencias, anule los bloques try/finally.

Otra cosa que está haciendo su código es suponer que el contenido devuelto está codificado en el juego de caracteres predeterminado de su máquina virtual (aunque eso podría ser adecuado, dependiendo del caso de uso).

1

Tiene razón, si utiliza BufferedReader para leer el contenido HTTP y los encabezados, querrá InputStreamReader para que pueda leer el byte de byte.

BufferedReader en este escenario a veces hace cosas raras ... especialmente cuando se trata de leer encabezados HTTP POST, a veces no podrá leer los datos POST, si utiliza el InputStreamReader puede leer la longitud del contenido y leer muchos bytes ...

0

Mi instinto me dice que, dado que ya está realizando el almacenamiento en búfer mediante el uso de la matriz de bytes, es redundante utilizar el BufferedReader.

1

Cada invocación de uno de un InputStreamReader 's de lectura() métodos pueden causar uno o más bytes para ser leído desde el flujo de bytes de entrada de subyacente. Para permitir la conversión eficiente de bytes a caracteres, se pueden leer más bytes de la secuencia subyacente de los necesarios para satisfacer la operación de lectura actual.

Cuestiones relacionadas