Meilleures pratiques pour créer et télécharger un ZIP énorme (à partir de plusieurs BLOB) dans une WebApp
J'ai besoin de réaliser un massif de téléchargement de fichiers à partir de mon Application Web.
Il est évidemment prévu pour être une longue action (il sera utilisé une fois par année [par client]), de sorte que le temps n'est pas un problème (à moins qu'il frappe certaines délai d'attente, mais je peux gérer que par la création d'une certaine forme de keepalive heartbeating). Je sais comment créer un caché iframe et l'utiliser avec content-disposition: attachment
tente de télécharger le fichier au lieu de l'ouvrir dans le navigateur, et comment l'exemple d'une communication client-serveur pour le dessin d'une jauge de progression;
La taille réelle de le télécharger (et le nombre de fichiers) est inconnue, mais pour simplifier, on peut presque le considérer comme 1 GO, composé de 100 fichiers de 10 mo.
Depuis ce doit être un one-cliquez sur l'opération, ma première pensée a été de regrouper tous les fichiers, lors de la lecture à partir de la base de données, généré dynamiquement, un ZIP, puis demander à l'utilisateur d'enregistrer le ZIP.
La question est: quelles sont les pratiques exemplaires, et quels sont les inconvénients et les pièges, dans la création d'une énorme archive de plusieurs petits tableaux d'octets dans une WebApp?
Qui peuvent être aléatoirement divisés en:
- doit chaque tableau d'octets être converti en un fichier temporaire, ou peuvent-ils être ajoutés à l'ZIP dans la mémoire ?
- si oui, je sais que je vais avoir à gérer le possible, l'égalité de noms (ils peuvent avoir le même nom dans différents enregistrements dans la base de données, mais pas à l'intérieur du même système de fichiers, ni ZIP): est-il possible d'autres problèmes qui viennent à l'esprit (en supposant que le système de fichiers a toujours assez d'espace physique) ?
- puisque je ne peux pas compter sur d'avoir assez de RAM pour exécuter l'ensemble de l'opération en mémoire, je suppose que le ZIP doit être créé et nourri dans le système de fichiers avant d'être envoyé à l'utilisateur; est-il possible de faire autrement (par exemple avec websocket), comme de demander à l'utilisateur l'emplacement où enregistrer le fichier, et ensuite, à partir d'un flux constant de données à partir du serveur vers le client (Sci-Fi je suppose) ?
- d'autres problèmes connus ou des meilleures pratiques qui traversent votre esprit serait grandement apprécié.
source d'informationauteur Andrea Ligios
Vous devez vous connecter pour publier un commentaire.
Pour les gros contenu qui ne tiennent pas en mémoire à la fois, flux le contenu de la base de données de la réponse.
Ce genre de chose est en fait assez simple. Vous n'avez pas besoin d'AJAX ou les websockets, il est possible de transférer de gros fichiers de téléchargements via un simple lien sur lequel l'utilisateur clique sur. Et les navigateurs modernes ont décent gestionnaires de téléchargement avec leurs propres barres de progression - pourquoi réinventer la roue?
Si l'écriture d'une servlet à partir de zéro pour cela, obtenir l'accès à la base de données d'objets BLOB, l'obtention de ses flux d'entrée et de copier le contenu grâce à la réponse HTTP flux de sortie. Si vous avez Apache Commons IO bibliothèque, vous pouvez utiliser IOUtils.copier()sinon vous pouvez le faire vous-même.
La création d'un fichier ZIP à la volée peut être fait avec une ZipOutputStream. Créer l'un de ces plus de la réponse au flux de sortie (à partir de la servlet ou quel que soit votre cadre vous donne), puis obtenir de chaque GOUTTE de la base de données, à l'aide de
putNextEntry()
d'abord et ensuite streaming chaque GOUTTE comme décrit précédemment.Pièges Potentiels/Questions:
ZipOutputStream
si c'est un problème.Kick-off exemple de totalement dynamique fichier ZIP créé en streaming chaque BLOB à partir de la base de données directement au Système de Fichiers client.
Testé avec d'énormes archives avec les numéros suivants:
FileStreamDto.java à l'aide de
InputStream
au lieu debyte[]
Java Servlet (ou Struts2 Action)
Méthode d'assistance pour la manipulation des entrées en double
Merci beaucoup @prunge de me donner l'idée de le streaming direct.
Peut-être vous voulez essayer plusieurs téléchargements en même temps. J'ai trouvé une discussion sur ce sujet ici - Java multithread les performances de téléchargement de fichier
Espère que cette aide.