2021年7月4日 星期日

Zip/Unzip folder in Node.js

First, install jszip by npm install jszip, then paste the following code

Then you can use genZip("folder/to/zip","abc.zip") and extractZip("abc.zip","folder/to/extract/to") as promises to zip/unzip your folder

You can also pass an Array to genZip's first argument to zip multiple files and folders



{

let fs = require('fs');
let path = require('path');
let util = require("util");
let stat = util.promisify(fs.stat);
let rf=util.promisify(fs.readFile);
let wf=util.promisify(fs.writeFile);

let walk = function(dir, done) {
  var results = [];
  fs.readdir(dir, function(err, list) {
    if (err) return done(err);
    var i = 0;
    (function next() {
      var file = list[i++];
      if (!file) return done(null, results);
      file = path.resolve(dir, file);
      fs.stat(file, function(err, stat) {
        if (stat && stat.isDirectory()) {
          walk(file, function(err, res) {
            results = results.concat(res);
            next();
          });
        } else {
          results.push(file);
          next();
        }
      });
    })();
  });
};

let listFolderR=util.promisify(walk);

async function makeFolder(dpath)
{
  var mkdir=util.promisify(fs.mkdir)
  
  var farr=dpath.replace(/\\/g,"/").split("/");
  var tmpf=farr[0];
  var tflag=false;
  for(let [ind,ii] of Object.entries(farr))
    {
      if(ind>0) tmpf+="/"+ii;
	  try{
      var s=await stat(tmpf);
	  }catch(e){var s=null;}
	  
	  var tde=s && s.isDirectory();
      var fde=s && s.isFile();
      if(!tde && !fde)
        await mkdir(tmpf);
      else if(!tde && fde)
        {
          return "Error";
        }
    };
  return "Success";
}

function genZip(dir,zipFilePath)
{
  return new Promise(async (resolve)=>
	{
		var JSZip=require("jszip")
		var zip=new JSZip()
		
		var dirArr=[];
		
		if(typeof(dir)=="string")
			dirArr.push(dir);
		else if(dir && dir.constructor && dir.constructor.name=="Array")
			dirArr.push(...dir);
		
		for(let d of dirArr)
		{
		  try{
		  var s=await stat(d);
		  if(s && s.isDirectory())
		  {
	        var files=await listFolderR(d);
		  }
		  else
			var files=[d];
		
	  	  var pwd=path.resolve(d).replace(/\\/g,"/");
		  pwd=pwd.substr(0,pwd.lastIndexOf("/")+1)
		
		
		  for(let i of files)
		    zip.file(i.replace(/\\/g,"/").replace(pwd,""),await rf(i));
		  }catch(e){console.log(e);}

		}
		
		zip.generateNodeStream({type:"nodebuffer",
		                 streamFiles:true,
								compression: "DEFLATE",
                       compressionOptions: 
                         {
                           level: 5
                         }
							   })
		.pipe(fs.createWriteStream(zipFilePath))
		.on("finish",resolve);
	});
}

function extractZip(zipFilePath,extractionPath)
{
return new Promise(async (resolve)=>
{


  var zipobj=await require("jszip").loadAsync(await rf(zipFilePath));
  for(f of Object.values(zipobj.files))
  {
	if(!f.dir)
      await wf(extractionPath+"/"+f.name,f._data.compressedContent);
    else
	  await makeFolder(extractionPath+"/"+f.name);
  }
  resolve("Success");
});
}


}
	


沒有留言: