Je n'ai trouvé aucune bibliothèque préfabriquée prenant en charge la compression pouvant être reprise de la manière requise. Il y a, cependant, beaucoup de morceaux disponibles sous des licences ouvertes pour écrire les vôtres. J'ai maintenant une solution client/serveur qui satisfait toutes les contraintes décrites dans la question. L'idée est similaire aux idées de segmentation décrites ci-dessus, mais le serveur gère le découpage et fait une certaine comptabilité qui mappe les morceaux compressés sur le client aux morceaux compressés sur le serveur. Il n'y a aucun fichier temporaire dans la solution. Le protocole de base est la suivante
(1) The client sends a manifest to the server, containing the
to-be contents of the zip file
(2) The server sends back an ID for the manifest
Then repeatedly
(3) The client asks the server "is there anything still
required for the manifest with ID X"
(4) The server replies "no", or with a manifest entry
for a file in the manifest, plus a offset and length to send
(5) The client compresses that chunk and sends it (plus some
bookkeeping info)
(6) The server puts the chunk into the every growing zip file,
plus appropriate zip file crud. If the server orders
the chunks it asks the client for appropriately, this can
all be done by file appends.
Le serveur met à jour le manifeste seulement chaque pas de temps 6 se termine avec succès, de sorte que les défaillances au cours des étapes 3-6 (y compris les accidents sur le serveur ou le client) peuvent être repris en toute sécurité (bien, plus ou moins).
Il y a quelques bits qui ont été un peu fastidieux dans la création de fichiers zip en bloc. La chose de base qui doit être réalisée est de trouver un algorithme de compression capable de chunk-capable. Dégonfler peut être utilisé de cette manière.
Les java ZipOutputStream et DeflaterOutputStream ne conviennent pas vraiment pour le dégonflage/zipping «en bloc», car ils ne permettent pas un rinçage arbitraire. Il existe une implémentation Java sous licence de style BSD de ZLib au http://www.jcraft.com/jzlib. Je ne l'ai pas référencé pour la vitesse, mais il donne la même sortie que l'implémentation Java. JZLib est génial, et supporte tous les modes de vidage de ZLib (contrairement à l'implémentation de java.util.zip.Deflate).
De plus, les fichiers Zip calculent un CRC pour chaque entrée. Ainsi, l'entrée manifeste à l'étape 4 contient un CRC «partiel», qui est mis à jour pour chaque segment et renvoyé dans les informations de comptabilité à l'étape 5. Il existe une implémentation du domaine public CRC pour Java au http://www.axlradius.com/freestuff/CRC32.java. Je l'ai comparé et il est aussi rapide que (et fournit des CRC équivalents) l'implémentation Java native.
Enfin, le format de fichier Zip est assez pernickety. J'ai réussi à assembler la plupart d'une mise en œuvre de la page wikipedia et http://www.pkware.com/documents/casestudies/APPNOTE.TXT. Bien qu'à un moment je ne pouvais pas travailler la bonne valeur pour l'un des champs. Heureusement, la source ZipOutputStream du JDK est disponible pour que vous puissiez voir ce qu'ils font.
Quelques personnes ont suggéré le découpage. C'est une bonne idée, sauf pour la condition (2) ci-dessus. Si je tronque, je n'ai aucun moyen (que je sache) de faire un fichier .zip/.gz valide à partir des morceaux. –
Comme je l'ai dit, vous devrez soit stocker un fichier sur le client ou réassembler sur le serveur. La seule alternative consiste à charger efficacement le fichier entier en mémoire et à créer une version en mémoire du fichier sur le client de toute façon. – cletus