descarga de archivos de gran tamaño con servlet

Yo estoy usando el Apache Servidor Tomcat 6 y Java 1.6 y estoy tratando de escribir grandes archivos mp3 a la ServletOutputStream para que un usuario pueda descargar. Los archivos que van desde un 50-750MB en el momento.

Los archivos más pequeños, no causando demasiado de un problema, pero con los archivos más grandes y obtener socket excepción tubería rota.

File fileMp3 = new File(objDownloadSong.getStrSongFolder() + "/" + strSongIdName);
FileInputStream fis = new FileInputStream(fileMp3);
response.setContentType("audio/mpeg");
response.setHeader("Content-Disposition", "attachment; filename=\"" + strSongName + ".mp3\";");
response.setContentLength((int) fileMp3.length());
OutputStream os = response.getOutputStream();

try {
    int byteRead = 0;
    while ((byteRead = fis.read()) != -1) {
        os.write(byteRead);
    }
    os.flush();
} catch (Exception excp) {
    downloadComplete = "-1";
    excp.printStackTrace();
} finally {
    os.close();
    fis.close();
}
InformationsquelleAutor niks | 2010-05-12

3 Kommentare

  1. 5

    pero con los archivos más grandes parece que está siendo escrito en el montón que luego causando un OutOfMemory error y derribando a todo el servidor

    La causa se encuentra en algún lugar más que en la medida de determinado fragmento de código. Una de las causas sería la lectura de la toda la archivo en un byte[], pero que no parece suceder en el código que has publicado. También, Tomcat 6 por defecto auto-limpia la secuencia de respuesta en cada una de 2KB. En el futuro, por favor incluir todo el stacktrace en la pregunta así. Podría indicar que HttpServletResponseWrapper y/o un Filter en la cadena de la que es posiblemente el búfer de toda la respuesta.

    también socket excepción tubería rota.

    Esto solo significa que la otra parte ha abortado la solicitud. Nada que hacer contra desde el lado del servidor y debe técnicamente también no hacer daño. Puede ignorarlo.

    • Gracias Balus,pero mi principal problema es que yo no soy capaz de descargar los archivos en el lado del cliente y no obtener ningún resposne de error .quiero descargar grandes archivos decir abt 10 mb .
    • Sí, eso lo entiendo. ¿Entiende usted mi respuesta? ¿Te diste cuenta de la parte sobre el stacktrace?
    • u me quiere mostrar toda excepción.sí me di cuenta ,si m falta sumthing me dejó sin.
  2. 1

    Que son la escritura de los archivos que son de 3/4s de un concierto de un byte a la vez?

    Trate de usar un buffer más largo.

    int BUFF_SIZE = 1024;
    byte[] buffer = new byte[BUFF_SIZE];
    File fileMp3 = new File(objDownloadSong.getStrSongFolder() + "/" + strSongIdName);
    FileInputStream fis = new FileInputStream(fileMp3);
    response.setContentType("audio/mpeg");
    response.setHeader("Content-Disposition", "attachment; filename=\"" + strSongName + ".mp3\";");
    response.setContentLength((int) fileMp3.length());
    OutputStream os = response.getOutputStream();
    int byteCount = 0;
    try {
        do {
            byteCount = fis.read(buffer);
            if (byteCount == -1)
               break;
            os.write(buffer, 0, byteCount);
            os.flush();
        } while (true);
    }
    } catch (Exception excp) {
        downloadComplete = "-1";
        excp.printStackTrace();
    } finally {
        os.close();
        fis.close();
    }

    Por CIERTO, antes de empezar a responder a esta pregunta he empezado vacío de un bucle que se repetirá 750,000,000,000 (su tamaño de archivo grande) veces para ver cuánto tiempo tarda. Aún funciona.

    • Lo siento, pero no puedo ver cómo un buffer más grande podría resolver este problema. Esto sólo hará que sea más rápido y consume (un poco) más memoria. El OutOfMemoryError ciertamente no puede ser causado por un «buffer» de 1 byte como el OP está utilizando. La tubería de error significa que el otro lado (el cliente) ha anulado la conexión/petición/descarga de sí mismo, esto no está relacionado con el lado del servidor de código.
  3. 0

    Un problema común con la descarga de archivos grandes es que son de almacenar el archivo completo, lo que puede causar rotura de la tubería si el cliente no es lo suficientemente paciente. También puede ejecutar fuera de la memoria en el servidor cuando el archivo es demasiado grande.

    Intentar forzar la codificación fragmentada por hacer esto,

    response.setContentLength(-1);

    Esto hará que el conector de corriente el archivo pedazo a pedazo.

    • Por defecto Tomcat búferes de no más de 2K y autoflushes la respuesta. Así que dudo si esa es la causa raíz. Codificación fragmentada puede por el camino también se activa sólo por la omisión de toda setContentLength() llamada.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea