As I’ve been working on a small project for the past few months, mostly related to backend processing – files, databases etc. The small part of the project needed the ability to read and write zip files. I found the jsZip npm package adequate for my requirement. This allows me to quickly read and write zip files.
Installation with npm is as usual.
npm install jszip |
Reading zip files
First we will see how to read a zip file from your local directory. Assuming you have a file named ‘project.zip’ which includes a few JavaScript files.
var fs = require("fs"); var JSZip = require("jszip"); // read a zip file fs.readFile("project.zip", function(err, data) { if (err) throw err; JSZip.loadAsync(data).then(function (zip) { files = Object.keys(zip.files); console.log(files); }); }); |
This will return the names of the files in the zip file.
[ 'file-monitor.js', 'file-set.js', 'filenamify.js', 'form-data.js', 'fuzzball.js', 'gmail.js' ] |
The general structure of the zip file object returned is given below.
{ files: { 'file-monitor.js': { name: 'file-monitor.js', dir: false, date: 2018-05-01T09:52:56.000Z, comment: null, unixPermissions: null, dosPermissions: 32, _data: { compressedSize: 293, uncompressedSize: 612, crc32: -1393654514, compression: [Object], compressedContent: <Buffer 85 51 cd 4a 03 31 10 be 2f ec... 26 98 a4 5d 44 7c 77 67 b2 dd 35 d0 83 87 10 32 f3 fd ... > }, _dataBinary: true, options: { compression: null, compressionOptions: null } }, 'file-set.js': |
We read the filenames using the following.
files = Object.keys(zip.files); |
To get additional details for each file we can do the following.
// Get additional details for the file 'file-monitor.js' console.log(zip.files['file-monitor.js']); |
Now we can iterate over all the files and display additional details for each.
// read a zip file fs.readFile("project.zip", function(err, data) { if (err) throw err; JSZip.loadAsync(data).then(function (zip) { // Get list of filenames, which are also keys for additional details files = Object.keys(zip.files); for(i=0; i< files.length; i++){ console.log(files[i] + " " + zip.files[files[i]].date); } }); }); |
To read the contents of a file in the zip archive you can use the following. Assume you have a ‘Hello.txt’ file in the zip archive with the content ‘Hello World!’.
// read a zip file fs.readFile("project.zip", function(err, data) { if (err) throw err; JSZip.loadAsync(data).then(function (zip) { // Read the contents of the 'Hello.txt' file zip.file("Hello.txt").async("string").then(function (data) { // data is "Hello World!" console.log(data); }); }); }); |
We are using the ‘string’ type here when reading the file, but you can use other types supported by jsZip.
Possible values for type :
base64 : the result will be a string, the binary in a base64 form.
text (or string): the result will be an unicode string.
binarystring: the result will be a string in ‘binary’ form, using 1 byte per char (2 bytes).
array: the result will be an Array of bytes (numbers between 0 and 255).
uint8array : the result will be a Uint8Array. This requires a compatible browser.
arraybuffer : the result will be a ArrayBuffer. This requires a compatible browser.
blob : the result will be a Blob. This requires a compatible browser.
nodebuffer : the result will be a nodejs Buffer. This requires nodejs.
Example:
zip.file("image.png").async("uint8array").then(function (u8) { // ... }); |
All formats will not be supported on all OS platforms so check before using.
if (JSZip.support.string) { zip.file("Hello.txt").async("string").then(function (data) { // data is "Hello World!" console.log(data); }); } |
Writing zip files
Creating a zip file is a little involved as compared to reading a zip file.
var fs = require("fs"); var JSZip = require("jszip"); var zip = new JSZip(); // Add a top-level, arbitrary text file with contents zip.file("Hello.txt", "Hello World\n"); // Create a directory within the Zip file structure var img = zip.folder("images"); // Sample image data imgData = 'R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'; // Add a file to the 'images' directory, // and add an image with data URI as contents. img.file("star.gif", imgData, {base64: true}); // JSZip can generate Buffers so you can do the following zip.generateNodeStream({type:'nodebuffer',streamFiles:true}) .pipe(fs.createWriteStream('out.zip')) .on('finish', function () { // JSZip generates a readable stream with a "end" event, // but is piped here in a writable stream which emits a "finish" event. console.log("out.zip written."); }); |