Décompression des fichiers
Je veux afficher les fichiers OpenOffice ,.odt et .odp côté client à l'aide d'un navigateur web.
Ces fichiers sont des fichiers compressés. En utilisant Ajax, je peux obtenir ces fichiers du serveur mais ce sont des fichiers compressés. Je dois les décompresser en utilisant 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?
6 réponses
J'ai écrit un décompresseur en Javascript. Elle fonctionne.
Il s'appuie sur le lecteur de fichiers binaires D'Andy G. P. Na et certains RFC1951 gonflent la logique de notmasteryet . J'ai ajouté de la classe ZipFile.
Exemple de Travail:
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 la source est un fichier zip.page de démonstration htm, et 3 scripts distincts, un pour la classe zipfile, un pour la classe inflate et un pour une classe de lecteur de fichiers binaires. La démo dépend également de jQuery et jQuery UI. Si vous venez de télécharger le JS-zip.fichier zip, toute la source nécessaire est là.
Voici à quoi ressemble le code de L'application 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émo fonctionne en quelques étapes: le readFile
fn est déclenché par un cliquez sur, et instancie un objet ZipFile, qui lit le fichier zip. Il y a un rappel asynchrone lorsque la lecture se termine (généralement en moins d'une seconde pour les fermetures éclair de taille raisonnable) - dans cette démo, le rappel est maintenu dans la variable locale doneReading, qui appelle simplement extractEntries
, 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 par programme, etc.).
Le extractEntries
FN itère sur toutes les entrées, et appelle extract()
sur chacune, en passant un rappel. La décompression d'une entrée prend du temps, peut-être 1s ou plus pour chaque entrée dans le fichier zip, ce qui signifie que l'asynchronie est appropriée. Le rappel d'extrait ajoute simplement le contenu extrait à un accordéon jQuery sur la page. Si le contenu est binaire, il est formaté en tant que tel (non affiché).
Cela fonctionne, mais je pense que l'utilité est quelque peu limitée.
Pour une chose: C'est très lent. Prend ~4 secondes pour décompresser le 140k AppNote.fichier txt de PKWare. La même décompression peut être faite en moins de .5s dans un programme. Net. EDIT : le fichier zip Javascript se décompose considérablement plus rapidement que cela maintenant, dans IE9 et dans Chrome. Il est encore plus lent qu'un programme compilé, mais il est beaucoup rapide pour une utilisation normale du navigateur.
Pour un autre: il ne fait pas de streaming. Il slurps essentiellement dans tout le contenu du fichier zip dans mémoire. Dans un environnement de programmation "réel", vous pouvez lire uniquement 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 faire des e / s comme ça en javascript, pour autant que je sache, donc la seule option est de lire tout le zip en mémoire et d'y faire un accès aléatoire. Cela signifie qu'il va placer des exigences déraisonnables sur la mémoire système pour les gros fichiers zip. Pas tellement un problème pour un petit fichier zip.
Aussi: ce n'est pas le cas gérer le fichier zip" general case " - il y a beaucoup d'options zip que je n'ai pas pris la peine d'implémenter dans le cryptage ZIP De Type unzipper, le cryptage WinZip, zip64, noms de fichiers codés UTF - 8, et ainsi de suite. ( EDIT - il gère maintenant les noms de fichiers encodés en UTF-8). La classe ZipFile gère les bases, cependant. Certaines de ces choses ne seraient pas difficiles à mettre en œuvre. J'ai une classe de cryptage AES en Javascript; qui pourrait être intégrée pour prendre en charge le cryptage. Soutenir Zip64 serait probablement inutile pour la plupart des utilisateurs de Javascript, car il est destiné à supporter > 4GB zipfiles-n'ont pas besoin d'extraire ceux dans un navigateur.
Je n'ai pas non plus testé le cas pour décompresser le contenu binaire. En ce moment, il décompresse le texte. Si vous avez un fichier binaire compressé, vous devez modifier la classe ZipFile pour le gérer correctement. Je n'ai pas compris comment faire ça proprement. Il fait aussi des fichiers binaires maintenant.
EDIT - j'ai mis à jour la bibliothèque JS unzip et démo. Il fait maintenant des fichiers binaires, en plus du texte. Je l'ai rendu plus résilient et plus général - vous pouvez maintenant spécifier l'encodage à utiliser lors de la lecture de fichiers texte. La démo est également étendue - elle montre la décompression d'un fichier XLSX dans le navigateur, entre autres choses.
Donc, bien que je pense que c'est d'une utilité et d'un intérêt limités, cela fonctionne. Je suppose que cela fonctionnerait dans le nœud.js.
J'utilise zip.js et cela semble être très utile. Il vaut la peine un coup d'oeil!
Vérifiez la démoUnzip , par exemple.
J'ai trouvé jszip très utile. J'ai utilisé jusqu'à présent uniquement pour la lecture, mais ils ont créer/modifier des capacités.
Code sage il ressemble à quelque chose comme ceci
var new_zip = new JSZip();
new_zip.load(file);
new_zip.files["doc.xml"].asText() // this give you the text in the file
Une chose que j'ai remarquée est qu'il semble que le fichier doit être au format de flux binaire (lire en utilisant le .readAsArrayBuffer de FileReader (), sinon je recevais des erreurs disant que je pourrais avoir un fichier zip corrompu
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 actifs de base tels que javascript / CSS / images directement à partir du zip en utilisant des méthodes de classe. J'espère que ça aide
J'ai écrit "Binaire Outils pour JavaScript", un projet open source qui inclut la possibilité de décompresser, unrar et décompresser: https://github.com/codedread/bitjs
Utilisé dans mon lecteur de bande dessinée: https://github.com/codedread/kthoom (également open source).
HTH!