I am trying to use yauzl to unzip files. However the example in the repo does not show how to unzip to a folder. It simply says:
readStream.pipe(somewhere);
Is there an easy way to extract the contents to a folder?
I am trying to use yauzl to unzip files. However the example in the repo does not show how to unzip to a folder. It simply says:
readStream.pipe(somewhere);
Is there an easy way to extract the contents to a folder?
Hi :) Replacing 'readStream.pipe(somewhere);' with code under '//--------------------' tag below works for me and the example in the repo
import fs = require('fs');
const unzipper = require('unzipper');
const { pipeline, finished } = require('stream');
//--------------------
cons destDir = 'C:\MyPath'
const writer = fs.createWriteStream(path.join(destDir, entry.fileName));
readStream.pipe(writer);
await finished(readStream, (err) => {
if (err) {
console.error(' ### Streaming to writer failed: ', err);
} else {
console.log(' ### Streaming to writer succeded, file unzipped.');
}
};
DISCLAIMER: I am at the beginning of learning Node/ts! This works for me, but may be wrong to some reason/s.
Here's a promise returning function that does what you're asking with the following caveats:
mkdirp
external library. This can be removed if you're more careful with how you create your directories.zipFile.close()
statements before the rejects may be unnecessary.import path = require('path');
import yauzl = require('yauzl');
import mkdirp = require('mkdirp');
/**
* Example:
*
* await unzip("./tim.zip", "./");
*
* Will create directories:
*
* ./tim.zip
* ./tim
*
* @param zipPath Path to zip file.
* @param unzipToDir Path to the folder where the zip folder will be put.
*/
const unzip = (zipPath: string, unzipToDir: string) => {
return new Promise<void>((resolve, reject) => {
try {
// Create folder if not exists
mkdirp.sync(unzipToDir);
// Same as example we open the zip.
yauzl.open(zipPath, { lazyEntries: true }, (err, zipFile) => {
if (err) {
zipFile.close();
reject(err);
return;
}
// This is the key. We start by reading the first entry.
zipFile.readEntry();
// Now for every entry, we will write a file or dir
// to disk. Then call zipFile.readEntry() again to
// trigger the next cycle.
zipFile.on('entry', (entry) => {
try {
// Directories
if (/\/$/.test(entry.fileName)) {
// Create the directory then read the next entry.
mkdirp.sync(path.join(unzipToDir, entry.fileName));
zipFile.readEntry();
}
// Files
else {
// Write the file to disk.
zipFile.openReadStream(entry, (readErr, readStream) => {
if (readErr) {
zipFile.close();
reject(readErr);
return;
}
const file = fs.createWriteStream(path.join(unzipToDir, entry.fileName));
readStream.pipe(file);
file.on('finish', () => {
// Wait until the file is finished writing, then read the next entry.
// @ts-ignore: Typing for close() is wrong.
file.close(() => {
zipFile.readEntry();
});
file.on('error', (err) => {
zipFile.close();
reject(err);
});
});
}
}
catch (e) {
zipFile.close();
reject(e);
}
});
zipFile.on('end', (err) => {
resolve();
});
zipFile.on('error', (err) => {
zipFile.close();
reject(err);
});
});
}
catch (e) {
reject(e);
}
});
}