node.js自定义实现多级文件夹压缩,解压缩

压缩模块

const fs = require('fs');
const path=require('path');

// 文件路径/文件名/文件内容  固定取值范围  UInt16 2个字节 65535  63kb左右  UInt32 4个字节  4G左右
// 压缩单个文件夹
function toZip(filePath,zipPath) {
  if (!fs.existsSync(zipPath)) {
    fs.mkdirSync(zipPath);
  }
  // 声明根路径
  var fileArray = [];
  function getFilesObj(filePath) {
    // 读取当前要压缩的文件目录
    var files = fs.readdirSync(filePath);
    files.forEach((file,i) => {
      var inner = path.resolve(filePath, file);
      var lstat = fs.lstatSync(inner) || [];
      if(lstat.isDirectory()) {
         var __path = inner.replace(__dirname,'');
         var directory = {
            path: __path,
            isFile: false
         }
         fileArray.push(directory);
         getFilesObj(inner);
      }  else {
         var name = inner.replace(filePath, '').substring(1);
         var _path = inner.replace(__dirname,'');
         var fileDes = {
           name:name,
           path: _path,
           isFile: true
         }
         fileArray.push(fileDes)
       }
    })
    return fileArray
  }

  var package = getFilesObj(filePath);  
   var fileArray = []

  package.forEach((item,index)=> {
      if(item.isFile) { 
         var pathLen = new Buffer(1);
         pathLen.writeUInt8(item.path.length);
         var _path = new Buffer(item['path']);
         fileArray.push(pathLen)
         fileArray.push(_path)
         var nameLen = new Buffer(1);
         nameLen.writeUInt8(item.name.length);
         var name = new Buffer(item['name']);
         var content = fs.readFileSync(path.join(__dirname,item['path']));
         var contentLen = new Buffer(4);
         contentLen.writeUInt32BE(content.length);
         fileArray.push(nameLen)
         fileArray.push(name)
         fileArray.push(contentLen)
         fileArray.push(content)
      }
  })
 
  var result = Buffer.concat(fileArray);
  fs.writeFileSync(path.join(zipPath,'/lijiabing.xpkg'),result);
  console.log(result.toString(),'pp');
}

const input  = path.resolve(process.cwd(), './src');
const output = './build'
console.log(input)
toZip(input,output);

解压缩模块

const fs = require('fs');
const path=require('path');
const Files = './dist/lijiabing.xpkg';
const cp = require('child_process');

function toUnzip(Files) {

  var zipPack = fs.readFileSync(Files);
  var fileOffset = 0;
  function readFilesBuffer (zipFile) {
    if(fileOffset>zipFile.length-1) {
      return
    } 
    var pathLen = zipFile.readUInt8(fileOffset);
    fileOffset++;
    var _path = zipFile.toString('utf8',fileOffset,fileOffset+pathLen);
    fileOffset+= pathLen;
    var filenameLength = zipFile.readUInt8(fileOffset);
    fileOffset ++;
    var filename  = zipFile.toString('utf8',fileOffset,fileOffset+filenameLength);
    fileOffset += filenameLength;
    var contentLength = zipFile.readUInt32BE(fileOffset);
    fileOffset += 4;
    var file = zipFile.slice(fileOffset,fileOffset+contentLength);
    fileOffset += contentLength;
    console.log(filename)
    console.log(_path)
    console.log(_path.replace('/'+filename,''));
    let dirPath = 'unzipFile/'+_path.replace('/'+filename,'');
    cp.execSync('mkdir -p '+ dirPath);
    fs.writeFileSync(path.join(dirPath,filename),file);
    readFilesBuffer(zipFile)
  }
  readFilesBuffer(zipPack);
}
toUnzip(Files)

转载于:https://www.cnblogs.com/Lewiskycc/p/11303624.html

你可能感兴趣的:(node.js自定义实现多级文件夹压缩,解压缩)