Introduction to zip-stream
The zip-stream library is a powerful tool in Node.js that allows developers to create ZIP archives with a stream-based API. It provides an efficient way to generate ZIP files dynamically, which is particularly useful for handling large files or on-the-fly compression in web applications.
Getting Started
First, let’s start by installing the zip-stream
library via npm:
npm install zip-stream
Now, let’s include the library in your Node.js application:
const zipstream = require('zip-stream');
const fs = require('fs');
Basic Usage
Here’s a simple example of how to create a ZIP file and add files to it using zip-stream
:
const archive = new zipstream();
const output = fs.createWriteStream('output.zip');
archive.pipe(output);
// adding a file from the file system
archive.entry(fs.createReadStream('file1.txt'), { name: 'file1.txt' }, (err) => {
if (err) throw err;
// adding content directly
archive.entry('This is some content', { name: 'file2.txt' }, (err) => {
if (err) throw err;
// finalize the archive (no more entries)
archive.finalize();
});
});
Advanced Usage and API Examples
The zip-stream
library offers various methods to cater to different use cases. Below are some commonly used APIs:
Adding Entries with Different Options
You can customize the entries with additional options such as compression level, modification time, and more:
const archive = new zipstream();
const output = fs.createWriteStream('output.zip');
archive.pipe(output);
const options = {
name: 'file3.txt',
date: new Date(), // set the modification date
mode: 0o644, // file permissions
comment: 'This is a comment', // file comment
compression: 'DEFLATE', // custom compression method
};
archive.entry(fs.createReadStream('file3.txt'), options, (err) => {
if (err) throw err;
archive.finalize();
});
Using Buffers
zip-stream
allows you to add entries using buffers, providing flexibility in handling data:
const archive = new zipstream();
const output = fs.createWriteStream('output.zip');
archive.pipe(output);
const buffer = Buffer.from('This is some buffer content', 'utf-8');
archive.entry(buffer, { name: 'file4.txt' }, (err) => {
if (err) throw err;
archive.finalize();
});
Adding Directory Structures
zip-stream
can also handle directory structures by specifying the directory name in the entry options:
const archive = new zipstream();
const output = fs.createWriteStream('output.zip');
archive.pipe(output);
const dirOpts = {
name: 'myDirectory/',
};
archive.entry(null, dirOpts, (err) => {
if (err) throw err;
// Add files to the directory
archive.entry('File in directory', { name: 'myDirectory/file5.txt' }, (err) => {
if (err) throw err;
archive.finalize();
});
});
Application Example
Let’s create a simple Express.js application that allows users to download a dynamically generated ZIP file:
const express = require('express');
const zipstream = require('zip-stream');
const fs = require('fs');
const app = express();
app.get('/download-zip', (req, res) => {
res.setHeader('Content-Disposition', 'attachment; filename=example.zip');
const archive = new zipstream();
archive.pipe(res);
// Add files to the ZIP archive
archive.entry(fs.createReadStream('file1.txt'), { name: 'file1.txt' }, (err) => {
if (err) throw err;
archive.entry('Direct content file', { name: 'file2.txt' }, (err) => {
if (err) throw err;
// finalizing the archive
archive.finalize();
});
});
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
In this example, when a user accesses the /download-zip
endpoint, the server generates a ZIP file on-the-fly and sends it for download.
Hash: c557de44788e7b9d9e502b9a478989880d3f32402699304d917201461c7b6743