it-swarm.com.de

Dateien entpacken

Ich möchte OpenOffice Dateien, .odt und .odp auf der Clientseite mit einem Webbrowser anzeigen.

Diese Dateien sind komprimierte Dateien. Mit Ajax kann ich diese Dateien vom Server abrufen, es handelt sich jedoch um komprimierte Dateien. Ich muss sie mit JavaScript entpacken. Ich habe versucht, inflate.js zu verwenden. http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt , aber ohne Erfolg.

Wie kann ich das machen?

69
user69260

Ich habe einen Entpacker in Javascript geschrieben. Es klappt.

Es basiert auf Andy G.P. Na's Binärdateireader und einige RFC1951 blasen die Logik von notmasteryet auf . Ich habe die ZipFile-Klasse hinzugefügt.

arbeitsbeispiel:
http://cheeso.members.winisp.net/Unzip-Example.htm (Dead Link)

Die Quelle:
http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip (Dead Link)

[~ # ~] nb [~ # ~] : die Links sind tot; Ich werde bald einen neuen Gastgeber finden.

Die Quelle enthält eine ZipFile.htm-Demonstrationsseite und drei verschiedene Skripte, eines für die zipfile-Klasse, eines für die inflate-Klasse und eines für eine Klasse zum Lesen von Binärdateien. Die Demo hängt auch von jQuery und der jQuery-Benutzeroberfläche ab. Wenn Sie nur die Datei js-Zip.zip herunterladen, ist die gesamte erforderliche Quelle vorhanden.


So sieht der Anwendungscode in Javascript aus:

// 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 funktioniert in ein paar Schritten: Das readFile fn wird durch einen Klick ausgelöst und instanziiert ein ZipFile-Objekt, das die Zip-Datei liest. Es gibt einen asynchronen Rückruf, wenn der Lesevorgang abgeschlossen ist (in der Regel in weniger als einer Sekunde für ausreichend große Reißverschlüsse). In dieser Demo wird der Rückruf in der lokalen Variablen doneReading gespeichert, die einfach extractEntries aufruft und nur blind entpackt den gesamten Inhalt der bereitgestellten Zip-Datei. In einer echten App würden Sie wahrscheinlich einige der Einträge zum Extrahieren auswählen (dem Benutzer erlauben, einen oder mehrere Einträge programmgesteuert auszuwählen usw.).

Das extractEntries fn durchläuft alle Einträge und ruft extract() für jeden einzelnen auf, wobei ein Rückruf übergeben wird. Das Dekomprimieren eines Eintrags dauert einige Zeit, möglicherweise 1s oder mehr für jeden Eintrag in der Zip-Datei, was bedeutet, dass eine Asynchronität angemessen ist. Der Rückruf zum Extrahieren fügt den extrahierten Inhalt einfach 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 eingeschränkt ist.

Zum einen ist es sehr langsam. Das Entpacken der 140k AppNote.txt-Datei aus PKWare dauert ca. 4 Sekunden. Dieselbe Dekomprimierung kann in einem .NET-Programm in weniger als 0,5 Sekunden durchgeführt werden.  [~ # ~] edit [~ # ~] : Das Javascript ZipFile wird jetzt in IE9 und Chrome erheblich schneller entpackt. Es ist immer noch langsamer als ein kompiliertes Programm, aber für die normale Nutzung des Browsers ist es schnell genug.

Zum anderen: es macht kein Streaming. Es schlürft im Grunde den gesamten Inhalt der Zip-Datei in den Speicher. In einer "echten" Programmierumgebung könnten Sie nur die Metadaten einer Zip-Datei einlesen (z. B. 64 Bytes pro Eintrag) und dann die anderen Daten wie gewünscht lesen und dekomprimieren. Soweit ich weiß, gibt es in Javascript keine Möglichkeit, IO so zu machen. Daher besteht die einzige Möglichkeit darin, die gesamte Zip-Datei in den Speicher zu lesen und auf sie wahlfrei zuzugreifen. Dies bedeutet, dass für große Zip-Dateien unzumutbare Anforderungen an den Systemspeicher gestellt werden. Nicht so sehr ein Problem für eine kleinere Zip-Datei.

Außerdem: Die Zip-Datei "General Case" wird nicht verarbeitet - es gibt viele Zip-Optionen, die ich nicht im Entpacker implementiert habe - wie Zip-Verschlüsselung, WinZip-Verschlüsselung, Zip64, UTF-8-kodierte Dateinamen, und so weiter. ( [~ # ~] edit [~ # ~] - es behandelt jetzt UTF-8 kodierte Dateinamen). Die ZipFile-Klasse behandelt jedoch die Grundlagen. Einige dieser Dinge wären nicht schwer zu implementieren. Ich habe eine AES-Verschlüsselungsklasse in Javascript; das könnte integriert werden, um die Verschlüsselung zu unterstützen. Die Unterstützung von Zip64 wäre wahrscheinlich für die meisten Benutzer von Javascript nutzlos, da es Zip-Dateien mit mehr als 4 GB unterstützen soll - diese müssen nicht in einem Browser extrahiert werden.

Ich habe den Fall auch nicht zum Entpacken von Binärinhalten getestet. Im Moment wird der Text entpackt. Wenn Sie über eine komprimierte Binärdatei verfügen, müssen Sie die ZipFile-Klasse bearbeiten, um sie ordnungsgemäß verarbeiten zu können. Ich habe nicht herausgefunden, wie ich das sauber machen soll. Es macht jetzt auch Binärdateien.


[~ # ~] edit [~ # ~] - Ich habe die JS-Entpackungsbibliothek und -Demo aktualisiert. Es werden nun zusätzlich zu Text Binärdateien erstellt. Ich habe es widerstandsfähiger und allgemeiner gemacht - Sie können jetzt die Codierung angeben, die beim Lesen von Textdateien verwendet werden soll. Auch die Demo ist erweitert - sie 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.

61
Cheeso

Ich verwende Zip.js und es scheint ziemlich nützlich zu sein. Ein Blick lohnt sich!

Überprüfen Sie zum Beispiel die Demoversion entpacken .

24
Dani bISHOP

Ich fand jszip ziemlich nützlich. Bisher habe ich nur zum Lesen verwendet, aber sie haben auch Funktionen zum Erstellen/Bearbeiten.

Code weise sieht es so aus

var new_Zip = new JSZip();
new_Zip.load(file);
new_Zip.files["doc.xml"].asText() // this give you the text in the file

Eine Sache, die mir aufgefallen ist, ist, dass die Datei anscheinend im Binär-Stream-Format vorliegen muss (gelesen mit dem .readAsArrayBuffer von FileReader ())

11
AlvaroFG

Das Codebeispiel ist auf der Autorenseite . Sie können babelfish verwenden, um die Texte zu übersetzen (Japanisch nach Englisch).

Soweit ich Japanisch verstehe, soll diese Postleitzahl Zip-Daten (Streams) entschlüsseln, nicht Zip-Archiv.

2
OcuS

Ich habe auch dafür eine Klasse geschrieben. http://blog.another-d-mention.ro/programming/read-load-files-from-Zip-in-javascript/ Sie können grundlegende Elemente wie Javascript/CSS/Images direkt laden aus dem Zip mit Klassenmethoden. Ich hoffe es hilft

2
TheBrain

Wenn Sie auch andere Formate unterstützen müssen oder nur eine gute Leistung benötigen, können Sie diese WebAssembly-Bibliothek verwenden

es basiert auf Versprechungen, verwendet WebWorker für das Threading und API ist eigentlich ein einfaches ES-Modul

2
MySqlError

Ich habe "Binary Tools for JavaScript" geschrieben, ein Open-Source-Projekt, das das Entpacken, Entpacken und Entpacken von Dateien beinhaltet: https://github.com/codedread/bitjs

In meinem Comic-Reader verwendet: https://github.com/codedread/kthoom (auch Open Source).

HTH!

2
codedread