94 votes

Décompression des fichiers

Je veux afficher OpenOffice fichiers .odt et .odp à côté client à l'aide d'un navigateur web.

Ces fichiers sont des fichiers compressés. L'utilisation d'Ajax, je peux obtenir ces fichiers à partir du serveur, mais ce sont des fichiers compressés. J'ai pour décompresser à l'aide de JavaScript, j'ai essayé d'utiliser inflate.js, http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt, mais sans succès.

Comment puis-je faire cela?

63voto

Cheeso Points 87022

J'ai écrit un unzipper en Javascript. Elle fonctionne.

Il s'appuie sur Andy G. P. Na fichier binaire de lecteur et certains RFC1951 gonfler la logique de notmasteryet. J'ai ajouté de la classe ZipFile.

exemple:
http://cheeso.members.winisp.net/Unzip-Example.htm (lien mort)

La source:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip (lien mort)

NB: les liens sont morts, je vais trouver un nouvel hôte bientôt.

Inclus dans le source est un ZipFile.htm page de démonstration, et les 3 scripts distincts, l'un pour la classe zipfile, l'un pour le gonfler de classe, et l'autre pour un fichier binaire classe de lecteur. La démo dépend aussi de jQuery et jQuery UI. Si vous venez de télécharger la js-zip.zip fichier, tous les de la source nécessaire est là.


Voici ce que le code de l'application ressemble en Javascript:

// In my demo, this gets attached to a click event.
// it instantiates a ZipFile, and provides a callback that is
// invoked when the zip is read.  This can take a few seconds on a
// large zip file, so it's asynchronous. 
var readFile = function(){
    $("#status").html("<br/>");
    var url= $("#urlToLoad").val();
    var doneReading = function(zip){
        extractEntries(zip);
    };

    var zipFile = new ZipFile(url, doneReading);
};


// this function extracts the entries from an instantiated zip
function extractEntries(zip){
    $('#report').accordion('destroy');

    // clear
    $("#report").html('');

    var extractCb = function(id) {
        // this callback is invoked with the entry name, and entry text
        // in my demo, the text is just injected into an accordion panel.
        return (function(entryName, entryText){
            var content = entryText.replace(new RegExp( "\\n", "g" ), "<br/>");
            $("#"+id).html(content);
            $("#status").append("extract cb, entry(" + entryName + ")  id(" + id + ")<br/>");
            $('#report').accordion('destroy');
            $('#report').accordion({collapsible:true, active:false});
        });
    }

    // for each entry in the zip, extract it. 
    for (var i=0; i<zip.entries.length;  i++) {
        var entry = zip.entries[i];

        var entryInfo = "<h4><a>" + entry.name + "</a></h4>\n<div>";

        // contrive an id for the entry, make it unique
        var randomId = "id-"+ Math.floor((Math.random() * 1000000000));

        entryInfo += "<span class='inputDiv'><h4>Content:</h4><span id='" + randomId +
            "'></span></span></div>\n";

        // insert the info for one entry as the last child within the report div
        $("#report").append(entryInfo);

        // extract asynchronously
        entry.extract(extractCb(randomId));
    }
}

La démonstration fonctionne en deux étapes: L' readFile fn est déclenché par un clic, et instancie un ZipFile objet, qui lit le fichier zip. Il y a un rappel asynchrone pour une fois la lecture terminée (qui se produit généralement en moins d'une seconde de taille raisonnable, des zips) - dans cette démonstration, le rappel est tenue dans la doneReading variable locale, qui appelle tout simplement extractEntries, ce qui seulement aveuglément dézippe tout le contenu du fichier zip. Dans une application réelle, vous devriez probablement choisir un certain nombre d'entrées à extraire (permettre à l'utilisateur de sélectionner, ou choisir une ou plusieurs entrées de la programmation, etc).

L' extractEntries fn passe en revue toutes les entrées, et les appels extract() sur chacun d'eux, le passage d'un rappel. Décompression d'une entrée prend du temps, peut-être 1 ou plus pour chaque entrée dans la zipfile, ce qui signifie que l'asynchronie est approprié. L'extrait de rappel ajoute simplement l'extrait du contenu d'un accordéon jQuery sur la page. Si le contenu est binaire, alors il est formaté en tant que tel (pas montré).


Il fonctionne, mais je pense que l'utilité est assez limitée.

Pour une chose: C'est très lent. Prend environ 4 secondes pour décompresser les 140k AppNote.txt fichier de PKWare. La même décompresser peut être fait en moins de .5 dans une .NET programme. EDIT: Le Javascript ZipFile déballe beaucoup plus rapide que ce maintenant, dans IE9 et Chrome. Il est encore plus lent qu'un programme compilé, mais il est beaucoup rapide pour le mode normal d'utilisation du navigateur.

Pour un autre: il ne fait pas de streaming. Essentiellement, il slurps dans la totalité du contenu de la zipfile dans la mémoire. Dans un "vrai" environnement de programmation vous avez pu lire dans que les métadonnées d'un fichier zip (par exemple, 64 octets par entrée), puis lire et décompresser les autres données comme vous le souhaitez. Il n'y a aucun moyen de le faire IO comme ça en javascript, autant que je sache, donc la seule option est de lire l'intégralité du zip dans la mémoire et ne random access en elle. Cela signifie qu'il va placer des exigences déraisonnables de la mémoire système pour les gros fichiers zip. Pas tellement un problème pour un petit fichier zip.

Aussi: Il ne gère pas le "cas général" fichier zip - il y a beaucoup de zip options que je n'ai pas pris la peine de mettre en œuvre dans le unzipper - ZIP cryptage, WinZip chiffrement, zip64, codé en UTF-8 les noms de fichiers, et ainsi de suite. (EDIT - il gère l'UTF-8 noms de fichiers). La classe ZipFile gère les bases, si. Certaines de ces choses ne serait pas difficile à mettre en œuvre. J'ai un cryptage AES de classe en Javascript, qui pourrait être intégrée à prendre en charge le chiffrement. Soutenir Zip64 serait probablement inutile pour la plupart des utilisateurs de Javascript, comme il est destiné à soutenir >4 go zipfiles - n'ont pas besoin d'extraire celles-ci dans un navigateur.

J'ai aussi n'a pas le test est le cas pour la décompression du contenu binaire. Pour l'instant il ouvre le texte. Si vous avez un fichier compressé (fichier binaire, vous auriez besoin de modifier la classe ZipFile de le gérer correctement. Je n'ai pas trouver comment le faire proprement. Il n'fichiers binaires maintenant, trop.


EDIT - j'ai mis à jour la JS décompresser de la bibliothèque et de démonstration. C'est maintenant les fichiers binaires, en plus du texte. Je l'ai fait, plus résiliente et plus générale - vous pouvez maintenant spécifier l'encodage à utiliser lors de la lecture de fichiers texte. Aussi la démo est élargi, il montre la décompression d'un fichier XLSX dans le navigateur, entre autres choses.

Ainsi, alors que je pense qu'il est de peu d'utilité et d'intérêt, il fonctionne. Je suppose que ce serait travailler dans Node.js.

33voto

Dani bISHOP Points 856

J'utilise zip.js et cela semble être très utile. Ça vaut le coup d'oeil!

Vérifiez la démo Décompressez , par exemple.

4voto

codedread Points 511

J'ai écrit "Outils binaires pour JavaScript", un projet open source qui inclut la possibilité de décompresser, unrar et untar: https://code.google.com/p/bitjs/

Utilisé dans mon lecteur de bande dessinée: https://code.google.com/p/kthoom/ (également en source ouverte).

HTH!

2voto

OcuS Points 3633

Exemple de code est donné sur le site de l'auteur . Vous pouvez utiliser babelfish pour traduire les textes (japonais en anglais).

Pour autant que je comprenne le japonais, ce code de décompression est conçu pour décoder les données ZIP (flux) et non les archives ZIP.

2voto

TheBrain Points 2474

J'ai écrit un cours pour ça aussi. http://blog.another-d-mention.ro/programming/read-load-files-from-zip-in-javascript/ Vous pouvez charger des ressources de base telles que javascript / css / images directement à partir du zip en utilisant des méthodes de classe. J'espère que ça aide

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X