Estoy usando IBM Websphere Application Server v6 y Java 1.4 y estoy tratando de escribir archivos CSV grandes en el ServletOutputStream
para que los descargue un usuario. Los archivos van desde 50-750MB en este momento.Usando ServletOutputStream para escribir archivos muy grandes en un servlet Java sin problemas de memoria
Los archivos más pequeños no están causando demasiado problema, pero con los archivos más grandes parece que se está escribiendo en el montón que está causando un error OutOfMemory y derribando todo el servidor.
Estos archivos solo se pueden servir a los usuarios autenticados a través de HTTPS y es por eso que los estoy sirviendo a través de un Servlet en lugar de simplemente colocarlos en Apache.
El código que estoy utilizando es (un poco retirado en torno a esta pelusa):
resp.setHeader("Content-length", "" + fileLength);
resp.setContentType("application/vnd.ms-excel");
resp.setHeader("Content-Disposition","attachment; filename=\"export.csv\"");
FileInputStream inputStream = null;
try
{
inputStream = new FileInputStream(path);
byte[] buffer = new byte[1024];
int bytesRead = 0;
do
{
bytesRead = inputStream.read(buffer, offset, buffer.length);
resp.getOutputStream().write(buffer, 0, bytesRead);
}
while (bytesRead == buffer.length);
resp.getOutputStream().flush();
}
finally
{
if(inputStream != null)
inputStream.close();
}
El FileInputStream
no parece ser la causa de un problema, ya que si escribo a otro archivo o simplemente quitar la escritura por completo la el uso de la memoria no parece ser un problema.
Lo que estoy pensando es que el resp.getOutputStream().write
se está almacenando en la memoria hasta que los datos puedan enviarse al cliente. ¡De modo que el archivo completo podría leerse y almacenarse en el resp.getOutputStream()
causando problemas de memoria y fallando!
He intentado guardar estas secuencias en el búfer y también he intentado usar Canales desde java.nio
, ninguno de los cuales parece tener una pequeña diferencia en mis problemas de memoria. También he lavado el OutputStream
una vez por iteración del ciclo y después del ciclo, lo que no ayudó.
establecer esta propiedad personalizada de contenedor Web Websphere Try - com.ibm.ws.webcontainer.channelwritetype = sincronización detalles están aquí - http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/ index.jsp? topic =/com.ibm.websphere.express.doc/info/exp/ae/rweb_custom_props.html –