2012-09-24 8 views
6

En un servlet, estoy creando una gran cantidad de contenido HTML en un StringBuilder que, al final, debe escribirse en el PrintWriter de la respuesta. Para utilizar un PrintWriter, primero debe llamar al método toString() de StringBuilder para obtener el contenido como String. Pero esto innecesariamente duplica el contenido. ¿Hay alguna forma de escribir directamente desde StringBuilder ya que contiene el contenido?Escribir un StringBuilder en un escritor, sin toString()

PrintWriter puede aceptar una CharSequence, pero la documentación indica que llama al toString de CharSequence(), por lo que realmente no ayuda.

La única manera clara que puedo ver es usar el método charAt (i) de StringBuilder para obtener y escribir un carácter a la vez, pero ¿sería esto una mejora?

+2

La mejora es relativa. Si su objetivo es reducir el consumo de memoria, entonces sí sería una mejora. Deberías probar si es más lento. No me sorprendería si, debido al almacenamiento en búfer del flujo de salida, la penalización de rendimiento no fuera tan grande después de todo. –

Respuesta

7

Como alternativa, puede soltar el StringBuilder y usar un StringWriter y un PrintWriter.

+0

Necesito tomar el contenido HTML y escribirlo en el PrintWriter del Servlet, que se obtiene llamando al método getWriter() de HttpServletResponse. No veo una manera de combinar esto con un StringWriter. – worpet

2

Se podía escribir en el PrintStream en primer lugar, en vez de a la StringBuilder ...

Usando charAt definitivamente no le ayudará. Rendimiento muy pobre para hacerlo de esta manera. Si realmente desea continuar en esa dirección podría utilizar el método StringBuilder.subString(start,end). Este método le permitirá leer, por ejemplo, 1000 caracteres a la vez e imprimirlo en PrintWriter ...

+0

'StringBuilder.substring()' asignará una nueva Cadena cada vez que la llame. Aunque la cantidad total de memoria asignada será más pequeña, impone una gran sobrecarga. De hecho, creo que el uso de charAt() no será tan malo porque probablemente el PrintWriter del Servlet esté almacenado de todos modos. –

2

La clase StringBuilder almacena la cadena en una matriz de caracteres interna. El problema es que esta matriz de caracteres no es accesible.

Soluciones propuestas:

1) Se puede crear una nueva clase que se extiende ObjectOutputStream, donde reemplaza el método writeObjectOverride(Object obj). A continuación, simplemente serialice la instancia StringBuilder en la que ha construido su documento HTML. Su método reemplazado writeObjectOverride(Object obj) se invocará con la matriz de caracteres interna de Stringbuilder que forma parte del proceso de serialización, y listo: tiene la referencia de la matriz de caracteres interna del generador de cadenas, es suyo para escribirla en PrintWriter del servlet salida ... Nota: su método writeObjectOverride() se llamará varias veces, obviamente puede ignorar los que le pasan algo diferente de la matriz de caracteres deseada.

2) Puede usar la clase CharBuffer en lugar de StringBuilder que tiene el método array() que devuelve la matriz interna. CharBuffer no tiene la mayor cantidad de datos anexados (o PUT) como el StringBuilder, por lo que sería necesario para extender los un poco (dependiendo de lo que necesita exactamente) ...

3) Se puede escribir su propia implementación de StringBuilder, o mejor dicho, lo que usa de él. De esta forma, tendría acceso al objeto (una matriz char por ejemplo) en la que almacena el texto ensamblado ...

+0

No estoy seguro de que la solución 1 funcione porque para usar writeObjectOverride necesita volver a escribir la mayor parte de la lógica de serialización porque el constructor ObjectOutputStream de un parámetro deshabilita la llamada a writeObjectOverride. es decir, no está diseñado para usarse de esa manera. Además, no hay otros métodos que pueda llamar dentro de writeObjectOverride para manejar el caso normal. Aunque podría usar la reflexión, pero el gerente de seguridad podría interponerse en su camino. – cquezel

Cuestiones relacionadas