2013-03-26 12 views
45

Ich muss ein ganzes Verzeichnis mit Node.js zippen. Ich benutze derzeit node-zip und generiert bei jeder Ausführung des Prozesses eine ungültige ZIP-Datei (wie Sie aus this Github issue sehen können).Müssen ein gesamtes Verzeichnis mit Node.js ZIP ZIPen

Gibt es eine andere, bessere, Node.js Option, mit der ich ein Verzeichnis zippen kann?

EDIT: Ich landete archiver

writeZip = function(dir,name) { 
var zip = new JSZip(), 
    code = zip.folder(dir), 
    output = zip.generate(), 
    filename = ['jsd-',name,'.zip'].join(''); 

fs.writeFileSync(baseDir + filename, output); 
console.log('creating ' + filename); 
}; 

Beispielwert für Parameter mit bis:

dir = /tmp/jsd-<randomstring>/ 
name = <randomstring> 

UPDATE: Für jene über die Umsetzung zu fragen habe ich, here's a link to my downloader:

+0

Guter Ruf @booyaa. Vielen Dank. – commadelimited

+3

Jemand auf Twitter vorgeschlagen, die child_process-API, und rufen Sie einfach das System PLZ: http://nodejs.org/api/child_process.html – commadelimited

+1

Ich habe den child_process-Ansatz versucht. Es hat zwei Vorbehalte. ** 1) ** Unix 'zip' Befehl enthält alle übergeordneten Ordnerhierarchie des aktuellen Arbeitsverzeichnisses in der gezippten Datei. Das könnte für dich in Ordnung sein, es war nicht für mich. Auch das Ändern des aktuellen Arbeitsverzeichnisses in child_process wirkt sich nicht auf die Ergebnisse aus. ** 2) ** Um dieses Problem zu überwinden, müssen Sie 'pushd' verwenden, um in den Ordner zu springen, den Sie zippen und' zip -r', aber da 'pushd' in bash und nicht/bin/sh eingebaut ist Sie müssen auch/bin/bash verwenden. In meinem speziellen Fall war das nicht möglich. Nur ein Kopf hoch. – johnozbay

Antwort

71

Ich endete mit archiver lib. Funktioniert super.

Example

var file_system = require('fs'); 
var archiver = require('archiver'); 

var output = file_system.createWriteStream('target.zip'); 
var archive = archiver('zip'); 

output.on('close', function() { 
    console.log(archive.pointer() + ' total bytes'); 
    console.log('archiver has been finalized and the output file descriptor has closed.'); 
}); 

archive.on('error', function(err){ 
    throw err; 
}); 

archive.pipe(output); 
archive.bulk([ 
    { expand: true, cwd: 'source', src: ['**'], dest: 'source'} 
]); 
archive.finalize(); 
+1

Es scheint keine Beispiele zu geben, wie man das macht. Macht es Ihnen etwas auszumachen, was Sie getan haben? – Sinetheta

+3

Sicher Sache. Ich werde den ursprünglichen Beitrag aktualisieren. – commadelimited

+1

Archiver unterstützt ab sofort keine Unicode-Zeichen in Dateinamen. Berichtet an https://github.com/ctalkington/node-archiver/issues/90. – Eye

3

Adm -zip hat Probleme beim Komprimieren eines vorhandenen Archivs https://github.com/cthackers/adm-zip/issues/64 sowie cor Bruch mit komprimierenden Binärdateien.

Ich habe auch lief in Kompressionsfehler Probleme mit Knoten-zip https://github.com/daraosn/node-zip/issues/4

Knoten-Archivierungs ist das einzige, das gut zu funktionieren scheint zu komprimieren, aber es hat keine Dekomprimieren Funktionalität.

+1

Über welchen Knoten-Archiver sprichst du? : github.com/archiverjs/node-archiver; github.com/richardbolt/node-archiver – biphobe

+0

@firian Er sagte nicht Archiver, er sagte Adm-zip. –

+5

@FrancisPelland Umm, im letzten Satz schrieb er "_node-archiver ist der einzige, der scheint zu arbeiten_" - darauf bezog ich mich. – biphobe

10

Um alle Dateien und Verzeichnisse sind:

archive.bulk([ 
    { 
    expand: true, 
    cwd: "temp/freewheel-bvi-120", 
    src: ["**/*"], 
    dot: true 
    } 
]); 

Es nutzt Knoten-glob (https://github.com/isaacs/node-glob) unter, so dass jeder passenden Ausdruck damit kompatibel arbeiten.

2

Um Rohr das Ergebnis in das Antwortobjekt (Szenarien, in denen es notwendig ist, die zip herunterladen, anstatt lokal speichern)

archive.pipe(res); 

Sams Hinweise für den Zugriff auf den Inhalt des Verzeichnisses für mich gearbeitet.

src: ["**/*"] 
7

Archive.bulk jetzt veraltet ist, die neue Methode dafür verwendet werden soll glob:

var fileName = 'zipOutput.zip' 
var fileOutput = fs.createWriteStream(fileName); 

fileOutput.on('close', function() { 
    console.log(archive.pointer() + ' total bytes'); 
    console.log('archiver has been finalized and the output file descriptor has closed.'); 
}); 

archive.pipe(fileOutput); 
archive.glob("../dist/**/*"); //some glob pattern here 
archive.glob("../dist/.htaccess"); //another glob pattern 
// add as many as you like 
archive.on('error', function(err){ 
    throw err; 
}); 
archive.finalize(); 
+2

War sich darüber wundern, sagte sie Bulk war veraltet, aber schlug nicht vor, welche Funktion stattdessen zu verwenden. –

Verwandte Themen