What is node-stream-zip?
The node-stream-zip npm package is a library designed for node.js that allows for efficient, stream-based operations on ZIP archives. It enables reading entries, extracting files, and navigating through the structure of ZIP files without needing to decompress the entire archive upfront. This makes it particularly useful for applications that need to work with large ZIP files or require selective access to archive contents.
What are node-stream-zip's main functionalities?
Opening and reading ZIP archive
This code demonstrates how to open a ZIP file and read the number of entries (files and directories) it contains using the node-stream-zip package. It utilizes the async API for non-blocking operations.
const StreamZip = require('node-stream-zip');
const zip = new StreamZip.async({ file: './path/to/zipfile.zip' });
async function readZip() {
const entriesCount = await zip.entriesCount;
console.log(`Entries read: ${entriesCount}`);
await zip.close();
}
readZip();
Extracting a file from ZIP archive
This example shows how to extract a specific file from a ZIP archive to a desired location on the filesystem. It highlights the package's capability to handle individual file extraction efficiently.
const StreamZip = require('node-stream-zip');
const zip = new StreamZip.async({ file: './path/to/zipfile.zip' });
async function extractFile() {
await zip.extract('path/inside/zip.txt', './output/path/extracted.txt');
console.log('File extracted');
await zip.close();
}
extractFile();
Listing all entries in ZIP archive
This snippet is an example of how to list all entries (files and directories) in a ZIP archive. It demonstrates the package's ability to navigate and read the archive's structure.
const StreamZip = require('node-stream-zip');
const zip = new StreamZip.async({ file: './path/to/zipfile.zip' });
async function listEntries() {
const entries = await zip.entries();
for (const entry of Object.values(entries)) {
console.log(entry.name);
}
await zip.close();
}
listEntries();
Other packages similar to node-stream-zip
adm-zip
adm-zip is a JavaScript implementation for zip data compression for NodeJS. It provides functionalities similar to node-stream-zip, such as reading and extracting zip files. However, adm-zip does not focus as much on stream-based operations, which can make it less efficient for large files or selective extraction scenarios.
jszip
jszip is another popular library for creating, reading, and editing .zip files with JavaScript, both in node environments and in the browser. Unlike node-stream-zip, jszip offers broader compatibility with web applications but might not offer the same level of efficiency for node.js specific stream-based operations.
yauzl
yauzl is a minimalistic zip archive reader for Node.js, focusing on low memory usage. It is similar to node-stream-zip in its emphasis on non-blocking, stream-based operations for reading zip files. However, yauzl has a more minimalistic API and might require more manual handling for certain tasks compared to node-stream-zip.
node-stream-zip 
node.js library for reading and extraction of ZIP archives.
Features:
- it never loads entire archive into memory, everything is read by chunks
- large archives support
- all operations are non-blocking, no sync i/o
- fast initialization
- no dependencies, no binary addons
- decompression with built-in zlib module
- deflate, deflate64, sfx, macosx/windows built-in archives
- ZIP64 support
Installation
$ npm install node-stream-zip
Usage
Open a zip file
const StreamZip = require('node-stream-zip');
const zip = new StreamZip({
file: 'archive.zip',
storeEntries: true
});
zip.on('error', err => { });
List entries
zip.on('ready', () => {
console.log('Entries read: ' + zip.entriesCount);
for (const entry of Object.values(zip.entries())) {
const desc = entry.isDirectory ? 'directory' : `${entry.size} bytes`;
console.log(`Entry ${entry.name}: ${desc}`);
}
zip.close()
});
Stream one entry to stdout
zip.on('ready', () => {
zip.stream('path/inside/zip.txt', (err, stm) => {
stm.pipe(process.stdout);
stm.on('end', () => zip.close());
});
});
Extract one file to disk
zip.on('ready', () => {
zip.extract('path/inside/zip.txt', './extracted.txt', err => {
console.log(err ? 'Extract error' : 'Extracted');
zip.close();
});
});
Extract a folder from archive to disk
zip.on('ready', () => {
fs.mkdirSync('extracted');
zip.extract('path/inside/zip/', './extracted', err => {
console.log(err ? 'Extract error' : 'Extracted');
zip.close();
});
});
Extract everything
zip.on('ready', () => {
fs.mkdirSync('extracted');
zip.extract(null, './extracted', (err, count) => {
console.log(err ? 'Extract error' : `Extracted ${count} entries`);
zip.close();
});
});
Read a file as buffer in sync way
zip.on('ready', () => {
const data = zip.entryDataSync('path/inside/zip.txt');
zip.close();
});
When extracting a folder, you can listen to extract
event
zip.on('extract', (entry, file) => {
console.log(`Extracted ${entry.name} to ${file}`);
});
entry
event is generated for every entry during loading
zip.on('entry', entry => {
console.log(`Read entry ${entry.name}`);
});
Options
You can pass these options to the constructor
storeEntries: true
- you will be able to work with entries inside zip archive, otherwise the only way to access them is entry
eventskipEntryNameValidation: true
- by default, entry name is checked for malicious characters, like ../
or c:\123
, pass this flag to disable validation errors
Methods
zip.entries()
- get all entries descriptionzip.entry(name)
- get entry description by namezip.stream(entry, function(err, stm) { })
- get entry data reader streamzip.entryDataSync(entry)
- get entry data in sync wayzip.close()
- cleanup after all entries have been read, streamed, extracted, and you don't need the archive
Building
The project doesn't require building. To run unit tests with nodeunit:
$ npm test
Known issues
- utf8 file names
- AES encrypted files
Contributors
ZIP parsing code has been partially forked from cthackers/adm-zip (MIT license).