Ich schrieb einen Entpacker in Javascript. Es klappt.
Es beruht auf Andy G.P. Na's binary file reader und some RFC1951 inflate logic from notmasteryet. Ich habe die ZipFile-Klasse hinzugefügt.
Arbeitsbeispiel:
http://cheeso.members.winisp.net/Unzip-Example.htm (toter Link)
Die Quelle:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip (toter Link)
NB: die Links sind tot; Ich werde bald einen neuen Gastgeber finden.
In der Quelle enthalten ist eine ZipFile.htm-Demoseite und drei verschiedene Skripts, eines für die ZIP-Dateiklasse, eines für die Inflate-Klasse und eines für eine Binärdatei-Leserklasse. Die Demo hängt auch von jQuery und jQuery UI ab. Wenn Sie nur die Datei js-zip.zip herunterladen, sind alle erforderlichen Quellen vorhanden.
Hier ist, was der Anwendungscode wie in Javascript aussieht:
// 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));
}
}
Die Demo in ein paar Schritten arbeitet: Die readFile
fn durch einen Klick ausgelöst wird, und instanziiert ein ZipFile Objekt , die die Zip-Datei liest. Es gibt einen asynchronen Callback für den Abschluss des Lesevorgangs (normalerweise in weniger als einer Sekunde für sinnvoll dimensionierte Zips) - in dieser Demo wird der Callback in der lokalen Variablen doneReading gehalten, die einfach extractEntries
aufruft, die den gesamten Inhalt blind entpackt die bereitgestellte Zip-Datei. In einer echten App würden Sie wahrscheinlich einige der zu extrahierenden Einträge auswählen (dem Benutzer erlauben, auszuwählen oder einen oder mehrere Einträge programmgesteuert auszuwählen, usw.).
Die extractEntries
Fn iteriert über alle Einträge und ruft jeweils extract()
auf, wobei ein Callback übergeben wird. Die Dekomprimierung eines Eintrags benötigt Zeit, vielleicht 1s oder mehr für jeden Eintrag in der Zip-Datei, was bedeutet, dass Asynchronität angemessen ist. Der Extract-Callback fügt den extrahierten Inhalt einfach zu einem jQuery-Akkordeon auf der Seite hinzu. Wenn der Inhalt binär ist, wird er als solcher formatiert (nicht gezeigt).
Es funktioniert, aber ich denke, dass das Dienstprogramm etwas begrenzt ist.
Zum einen: Es ist sehr langsam. Nimmt ~ 4 Sekunden zum Entpacken des 140k AppNote.txt-Datei von PKWare. Die gleiche Dekomprimierung kann in weniger als 0,5 s in einem .NET-Programm durchgeführt werden.
EDIT: Die Javascript ZipFile entpackt wesentlich schneller als jetzt, in IE9 und in Chrome. Es ist immer noch langsamer als ein kompiliertes Programm, aber es ist viel schneller für die normale Browsernutzung.
Zum anderen: es tut nicht Streaming. Es schlürft grundsätzlich den gesamten Inhalt der Zip-Datei in den Speicher. In einer "echten" Programmierumgebung könnten Sie nur die Metadaten einer Zip-Datei (z. B. 64 Bytes pro Eintrag) einlesen und dann die anderen Daten wie gewünscht lesen und dekomprimieren. Es gibt keine Möglichkeit, IO in JavaScript zu machen, so weit ich weiß, daher ist die einzige Möglichkeit, die gesamte Zip in den Speicher zu lesen und wahllos darauf zuzugreifen. Das bedeutet, dass der Systemspeicher für große ZIP-Dateien unangemessen hohe Anforderungen stellt. Nicht so ein Problem für eine kleinere Zip-Datei.
Auch: Es funktioniert nicht die "allgemeine Fall" Zip-Datei - es gibt viele Zip-Optionen, die ich nicht in den Unzipper implementieren - wie ZIP-Verschlüsselung, WinZip-Verschlüsselung, Zip64,
UTF-8 kodierte Dateinamen,
und so weiter. (EDIT - es handhabt jetzt UTF-8 codierte Dateinamen). Die ZipFile-Klasse behandelt jedoch die Grundlagen. Einige dieser Dinge wären nicht schwer zu implementieren. Ich habe an AES encryption class in Javascript; das könnte integriert werden, um die Verschlüsselung zu unterstützen. Die Unterstützung von Zip64 würde wahrscheinlich für die meisten Benutzer von Javascript nutzlos sein, da es> 4GB-ZIP-Dateien unterstützen soll - diese müssen nicht in einem Browser extrahiert werden.
Ich habe auch nicht den Fall für das Entpacken binärer Inhalte getestet. Im Moment entzippt es den Text. Wenn Sie eine gezippte Binärdatei haben, müssten Sie die ZipFile-Klasse bearbeiten, um sie richtig zu handhaben. Ich habe nicht herausgefunden, wie ich das sauber machen soll.
Es tut jetzt auch binäre Dateien.
EDIT - ich die JS unzip Bibliothek und Demo aktualisiert. Es tut jetzt Binärdateien, zusätzlich zu Text. Ich habe es widerstandsfähiger und allgemeiner gemacht - Sie können jetzt die Codierung angeben, die beim Lesen von Textdateien verwendet werden soll. Auch das Demo ist erweitert - es zeigt unter anderem das Entpacken einer XLSX-Datei im Browser.
Also, während ich denke, dass es von begrenztem Nutzen und Interesse ist, funktioniert es. Ich denke, es würde in Node.js funktionieren.
"kein Erfolg" bitte seien Sie spezifischer, zeigen Sie uns einige Code, zeigen Sie uns einige Fehler ... Wir sind hier, um zu helfen, nicht zu erraten. – OcuS
Grundsätzlich habe ich einfach aufgeblasen Funktion - data = zip_inflate (src); Aber ich denke, das ist für einzelne Datei gemeint. Wenn ein zi p-Dateien enthalten mehrere Dateien in einer Verzeichnisstruktur, dann was ist der Inhalt von "Daten". Ich weiß nicht, wie man diese Bibliothek benutzt. – user69260
@Eimantas Was bedeutet das? + Oder - – user69260