Comprehensive Guide to zip-stream for Efficient ZIP File Creation in Node js

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

Leave a Reply

Your email address will not be published. Required fields are marked *