近期需要實(shí)現(xiàn)以下幾個(gè)需求,完成之后特此記錄,以供同學(xué)們參考:
1、使用node實(shí)現(xiàn)文件及文件夾進(jìn)行壓縮。
2、使用node實(shí)現(xiàn)zip加密壓縮(非對(duì)文件加密,是對(duì)壓縮包加密)。
3、使用node實(shí)現(xiàn)在不解壓zip包的前提下讀取其內(nèi)容。
4、使用node對(duì)zip包進(jìn)行偽加密。
安裝相關(guān)包及插件(需求1、2、3)
npm init -y //新建一個(gè)文件夾并且初始化node項(xiàng)目
npm i -S adm-zip //安裝adm-zip包
npm i -S archiver //安裝archiver包
npm i -S chilkat_node10_win32 //安裝chilkat_node10_win32包(只安裝了一個(gè)版本,以作演示)
關(guān)鍵代碼如下:
//index.js
var fs = require('fs'); //引入fs模塊,對(duì)文件進(jìn)行操作
var archiver = require('archiver'); // archiver可用于普通的打包壓縮
var AdmZip = require('adm-zip'); //用于讀取未解壓的zip包
var filePath = 'C:/Users/qingk/Desktop/test/src/' //獲取文件路徑
var dirList = fs.readdirSync(filePath); //獲取文件列表
var zipPath = 'C:/Users/qingk/Desktop/test/src.zip'; //壓縮包生成路徑
var level = 9; //壓縮等級(jí)
//創(chuàng)建最終打包文件的輸出流
var output = fs.createWriteStream(zipPath);
//生成archiver對(duì)象,打包類型為zip
var archive = archiver('zip', {
zlib: {
level: level
}
});
//功能一
//對(duì)文件進(jìn)行壓縮
// dirList.forEach(item=>{
// archive.append(fs.createReadStream(filePath+item), {'name': item});
// })
//對(duì)文件夾進(jìn)行壓縮
archive.directory(filePath, false);
archive.pipe(output); //將打包對(duì)象與輸出流關(guān)聯(lián)
//監(jiān)聽所有archive數(shù)據(jù)都寫完
output.on('close', function() {
console.log('壓縮完成', archive.pointer() / 1024 / 1024 + 'M');
// printData();
readZip();
});
archive.on('error', function(err) {
throw err;
});
//打包
archive.finalize();
//功能二
//不解壓的情況下讀取相關(guān)文件
function printData(){
var zip = new AdmZip(zipPath);
var zipEntries = zip.getEntries();
console.log(zipEntries);
zipEntries.forEach((item) => {
if(item.name=="a.txt")console.log(item.getData().toString());
if (item.isDirectory == false) {
console.log(item.getData().toString());
// this.text = item.getData().toString();
}
});
}
//功能三
// 使用Chilkat(選擇操作系統(tǒng)及工具)(貌似還收費(fèi))
// 參考地址:https://www.example-code.com/nodejs/zip_passwordProtect1.asp
// zip相關(guān)操作API:https://www.chilkatsoft.com/refdoc/nodejsZipRef.html
var os = require('os');
console.log(os.platform());
if (os.platform() == 'win32') {
var chilkat = require('chilkat_node10_win32');
} else if (os.platform() == 'linux') {
if (os.arch() == 'arm') {
var chilkat = require('chilkat_node10_arm');
} else if (os.arch() == 'x86') {
var chilkat = require('chilkat_node10_linux32');
} else {
var chilkat = require('chilkat_node10_linux64');
}
} else if (os.platform() == 'darwin') {
var chilkat = require('chilkat_node10_macosx');
}
function chilkatExample() {
var zip = new chilkat.Zip();
var success;
// Any string unlocks the component for the 1st 30-days.
success = zip.UnlockComponent("Anything for 30-day trial");
if (success !== true) {
console.log(zip.LastErrorText);
return;
}
success = zip.NewZip(zipPath);
if (success !== true) {
console.log(zip.LastErrorText);
return;
}
zip.SetPassword("00000");
zip.PasswordProtect = true;
var saveExtraPath;
saveExtraPath = true;
success = zip.AppendOneFileOrDir(zipPath,saveExtraPath);
console.log(success);
var success = zip.WriteZipAndClose();
if (success !== true) {
console.log(zip.LastErrorText);
return;
}
}
需求4:這里說下對(duì)于node實(shí)現(xiàn)zip包偽加密的思路,感興趣的同學(xué)可以自己去操作一下。
1、zip文件格式
[local file header + file data + data descriptor]{1,n} + central directory + end of central directory record
即
[文件頭+文件數(shù)據(jù)+數(shù)據(jù)描述符]{此處可重復(fù)n次}+核心目錄+目錄結(jié)束標(biāo)識(shí)
壓縮源文件數(shù)據(jù)部分:[local file header + file data + data descriptor]
其中,local file header 文件頭,用于標(biāo)識(shí)該文件的開始,記錄了該壓縮文件的信息。
| Offset | Bytes | Description | 翻譯 |
|---|---|---|---|
| 0 | 4 | Local file header signature = 0x04034b50 (read as a little-endian number) | 文件頭標(biāo)識(shí),值固定(0x04034b50) |
| 4 | 2 | Version needed to extract (minimum) | 解壓文件所需 pkware最低版本 |
| 6 | 2 | General purpose bit flag | 通用比特標(biāo)志位(置比特0位=加密) |
| 8 | 2 | Compression method | 壓縮方式 |
| 10 | 2 | File last modification time | 文件最后修改時(shí)間 |
| 12 | 2 | File last modification date | 文件最后修改日期 |
| 14 | 2 | CRC-32 | CRC-32校驗(yàn)碼 |
| 18 | 4 | Compressed size | 壓縮后的大小 |
| 22 | 4 | Uncompressed size | 未壓縮的大小 |
| 26 | 4 | File name length (n) | 文件名長(zhǎng)度 |
| 28 | 2 | Extra field length (m) | 擴(kuò)展區(qū)長(zhǎng)度 |
| 30 | n | File name | 文件名 |
| 30+n | m | Extra field | 擴(kuò)展區(qū) |
2、實(shí)現(xiàn)方式:通過node讀取壓縮包的buffer值,修改其中加密位的值(奇數(shù)為加密),就可以實(shí)現(xiàn)偽加密,需要記錄值以便解密。