Estoy escribiendo un software que, entre otras cosas, descarga un archivo zip usando la API de Dropbox y luego lo descomprime usando yauzl.
La forma en que los archivos se almacenan y descargan de la base de datos a menudo termina con carpetas anidadas, y necesito que siga siendo así.
Sin embargo, mi implementación de yauzl no es capaz de descomprimir manteniendo esa estructura de carpetas anidadas, si hay una carpeta anidada en el archivo, no se descomprime en absoluto.
Aquí está mi función de descompresión, que es el ejemplo predeterminado de Yauzl con la adición de escritura de archivo local al final.
const unzip = () => { let zipPath = "pathToFile.zip" let extractPath = "pathToExtractLocation" yauzl.open(zipPath, {lazyEntries: true}, function(err, zipfile) { if (err) throw err; zipfile.readEntry(); zipfile.on("entry", function(entry) { if (/\/$/.test(entry.fileName)) { // Directory file names end with '/'. // Note that entries for directories themselves are optional. // An entry's fileName implicitly requires its parent directories to exist. zipfile.readEntry(); } else { // file entry zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; readStream.on("end", function() { zipfile.readEntry(); }); const writer = fs.createWriteStream(path.join(extractPath, entry.fileName)); readStream.pipe(writer); }); } }); }); } Quitar la verificación if (/\/$/.test(entry.fileName)) trata la carpeta de nivel superior como un archivo, extrayéndolo sin extensión de archivo y con un tamaño de 0kb. Lo que quiero que haga es extraer el archivo, incluidas las subcarpetas (al menos a una profundidad de 2, teniendo en cuenta el riesgo de bombardeo zip).
¿Es eso posible usando yauzl?
El código necesita crear el árbol de directorios en la ruta de extracción. Puede usar fs.mkdir con la opción recursive para asegurarse de que exista un directorio antes de extraerlo.
if (/\/$/.test(entry.fileName)) { // Directory file names end with '/'. // Note that entries for directories themselves are optional. // An entry's fileName implicitly requires its parent directories to exist. zipfile.readEntry(); } else { // file entry fs.mkdir( path.join(extractPath, path.dirname(entry.fileName)), { recursive: true }, (err) => { if (err) throw err; zipfile.openReadStream(entry, function (err, readStream) { if (err) throw err; readStream.on("end", function () { zipfile.readEntry(); }); const writer = fs.createWriteStream( path.join(extractPath, entry.fileName) ); readStream.pipe(writer); }); } ); }