IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Servlets/JSP Java Discussion :

Téléchargement de gros fichiers depuis un Servlet


Sujet :

Servlets/JSP Java

  1. #1
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 33
    Par défaut Téléchargement de gros fichiers depuis un Servlet
    Bonjour,

    J'essaie de faire un Servlet dont la seule fonction est de lancer le téléchargement d'un fichier (depuis le serveur, vers le client). Le téléchargement se passe bien pour les petits fichiers, mais le serveur plante lamentablement dès que j'essaie avec des plus gros fichiers (>50mo) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    java.lang.OutOfMemoryError:*Java*heap*space
    org.apache.commons.io.output.ByteArrayOutputStream.needNewBuffer(ByteArrayOutputStream.java:124)
    org.apache.commons.io.output.ByteArrayOutputStream.write(ByteArrayOutputStream.java:155)
    org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1263)
    org.apache.commons.io.IOUtils.copy(IOUtils.java:1236)
    org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:360)
    org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:1360)
    com.becatalog.servlet.MediaDownload.doGet(MediaDownload.java:51)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    response.setContentType(type); // type du fichier
    response.setHeader("Content-Disposition", "attachment; filename="+name);
     
    File file = new File(DBInterface.getFinalDir(), name); // chemin vers le fichier
     
    ServletOutputStream out = response.getOutputStream();
     
    out.write(FileUtils.readFileToByteArray(file)); 
    out.flush();
    out.close();
    Bon, comme ça, ma première idée c'est de découper le fichier comme un bourin et de l'envoyer en pièces détachées, mais ça me parait long et pas très propre.
    Est ce que quelqu'un sait comment je dois m'y prendre pour envoyer un fichier de cette façon?

    Merci d'avance : )

  2. #2
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Par défaut
    On pourrait voir le code de ça FileUtils.readFileToByteArray(file)
    Je soupçonne que tu charges tout le contenu du fichier.
    Sinon c'est ton conteneur web qui bufferise trop et dans ce cas il faut "flusher" périodiquement.

    Attention il convient également de setter le content-length.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  3. #3
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 33
    Par défaut
    Bonjour et merci pour votre réponse!

    Citation Envoyé par Nemek Voir le message
    On pourrait voir le code de ça FileUtils.readFileToByteArray(file)
    FileUtils fait parti d'un paquet que j'ai téléchargé et ajouté à mon projet :
    http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html
    http://commons.apache.org/io/apidocs/org/apache/commons/io/FileUtils.html#readFileToByteArray(java.io.File)

    Citation Envoyé par Nemek Voir le message
    Je soupçonne que tu charges tout le contenu du fichier.
    Oui je pense aussi que ça vient de la, le fichier remplis toute la mémoire allouée à java et lance une exception.

    Citation Envoyé par Nemek Voir le message
    Sinon c'est ton conteneur web qui bufferise trop et dans ce cas il faut "flusher" périodiquement.
    Donc en gros, je charge le premier méga, je fais un flush, puis je charge le second... etc...?

  4. #4
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Par défaut
    C'était une idée mais normalement le conteneur devrait le gérer tout seul. Dès que son buffer est plein il envoie les données.

    Pour copier un flux c'est pas très compliqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static void copy(InputStream in, OutputStream out, int bufferSize) {
      byte[] buffer = new byte[bufferSize];
      int n;
      while ( (n=in.read(buffer, 0, bufferSize) >= 0) {
       out.write(buffer, 0, n);
      }
    }
     
    public static void copy(InputStream in, OutputStream out) {
      copy(in, out, 1024*8);
    }
    Tu peux utiliser la première méthode avec la taille du buffer de la réponse.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  5. #5
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 33
    Par défaut
    Merci à vous, ça marche parfaitement maintenant.

    Juste une dernière question, j'ai un problème à cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    response.setContentLength(file.length());
    setContentLength requière un entier, file.length() retourne un long. Si je cast ça ne posera pas de problème?

  6. #6
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Par défaut
    Potentiellement si car un fichier (en fonction du système de fichier et de sa configuration) un fichier peut avoir plus de 2^31-1 octets (soit environ 2Go)

    Cependant il n'est pas commun de transférer autant de données par HTTP.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  7. #7
    Membre averti
    Inscrit en
    Juillet 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 33
    Par défaut
    Okay, et bien encore une fois merci,

    Bonne journée à vous.
    Cordialement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 09/12/2010, 11h32
  2. Ecrire un fichier depuis une servlet
    Par aubertinp dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 23/10/2008, 14h12
  3. Accès fichier depuis une servlet
    Par dams2209 dans le forum Tomcat et TomEE
    Réponses: 1
    Dernier message: 23/10/2008, 12h49
  4. Comment charger un fichier depuis une Servlet
    Par g25452 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 22/08/2008, 13h50
  5. Téléchargement d'un fichier depuis une URL
    Par Fly3R dans le forum Windows Forms
    Réponses: 22
    Dernier message: 08/07/2007, 19h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo