基于Nodejs實(shí)現(xiàn)文件壓縮和解壓功能
在 windows 系統(tǒng)上面,我們壓縮文件,常常需要安裝一些壓縮軟件才能實(shí)現(xiàn)壓縮,可能有些還存在一些問題,例如 winrar 有廣告,7z 界面好像比較古老。
那么接下來我們就來學(xué)習(xí)一下怎么自己實(shí)現(xiàn)一個(gè)壓縮工具,徹底擺脫這些軟件。
ZIP 壓縮
ZIP 壓縮是一種廣泛使用的文件壓縮格式,它通過減小文件大小來節(jié)省存儲空間,同時(shí)便于文件的傳輸和分享。ZIP 文件不僅可以包含單個(gè)文件,還可以包含多個(gè)文件或文件夾,這些文件在壓縮過程中會被合并成一個(gè)單一的文件,這樣就方便了用戶管理和傳輸。
ZIP 壓縮算法主要利用了數(shù)據(jù)中的重復(fù)模式來減少文件的大小。當(dāng) ZIP 壓縮軟件發(fā)現(xiàn)數(shù)據(jù)中有重復(fù)的內(nèi)容時(shí),它會用更短的引用來替換這些重復(fù)內(nèi)容,從而達(dá)到減少文件大小的目的。這個(gè)過程是可逆的,意味著壓縮后的文件可以被解壓縮回原來的狀態(tài),不會有任何數(shù)據(jù)丟失。
使用 ZIP 壓縮的好處包括:
- 節(jié)省空間:ZIP 壓縮可以顯著減少文件的存儲空間需求,特別是對于包含大量重復(fù)數(shù)據(jù)的文件。
- 便于傳輸:減小的文件大小意味著在網(wǎng)絡(luò)上傳輸文件所需的時(shí)間更短,便于快速分享和下載。
- 整理文件:將多個(gè)文件和文件夾打包成單一的 ZIP 文件,可以簡化文件管理和分發(fā)。
雖然 ZIP 是一種非常有效的壓縮格式,但它并不總是能夠提供最佳的壓縮率。有些特定的壓縮算法,比如 7-Zip 的 LZMA 算法,可能在某些情況下提供更好的壓縮效率。因此,用戶在壓縮非常大的文件或需要極致壓縮率的場合時(shí),可能會考慮使用這些其他的壓縮工具和格式。
實(shí)現(xiàn)文件夾壓縮
我們最基礎(chǔ)的功能就是需要把一個(gè)文件夾弄成一個(gè)壓縮文件,最常見的場景就是微信傳文件不能傳文件,需要經(jīng)過壓縮:
要想使用,我們需要安裝一個(gè) adm-zip
包,它是一個(gè)用于 Node.js 的 JavaScript 實(shí)現(xiàn),可以處理 ZIP 文件的壓縮和解壓。它不依賴于任何原生代碼,易于安裝和使用。
pnpm add adm-zip
并編寫以下代碼:
const AdmZip = require("adm-zip"); const zip = new AdmZip(); // 添加整個(gè)目錄到 ZIP 文件 zip.addLocalFolder("./article"); // 定義 ZIP 文件的保存路徑 const outputPath = "./output.zip"; // 將 ZIP 文件保存到磁盤 zip.writeZip(outputPath, function (err) { if (err) { console.log("發(fā)生錯(cuò)誤:", err); } else { console.log("ZIP 文件成功創(chuàng)建:", outputPath); } });
ZIP 文件的創(chuàng)建和內(nèi)容的添加是在內(nèi)存中進(jìn)行的,直到你調(diào)用 writeZip 或 toBuffer 等方法將 ZIP 數(shù)據(jù)實(shí)際寫入到磁盤或其他存儲介質(zhì)之前,你是看不到任何新文件的。這種方式允許你在保存 ZIP 文件之前靈活地添加或修改內(nèi)容。
最終輸出效果正是我們想要的:
向壓縮文件中添加新內(nèi)容
接下來我們再看看新增內(nèi)容的,我們首先編寫如下代碼:
const AdmZip = require("adm-zip"); const zip = new AdmZip("./output.zip"); // 向ZIP文件中添加一個(gè)新文件,文件名為"newFile.txt",內(nèi)容為"Hello World" zip.addFile("moment.txt", Buffer.from("Hello World", "utf-8")); // 保存更改,覆蓋原有的ZIP文件 zip.writeZip("./output.zip"); console.log("新內(nèi)容已添加到ZIP文件中。");
這段代碼首先通過 Adm-Zip 加載一個(gè)已有的 ZIP 文件,然后使用 addFile 方法向其中添加一個(gè)新的文件。addFile 方法接受兩個(gè)參數(shù):第一個(gè)是要添加的文件名,第二個(gè)是文件的內(nèi)容,以 Buffer 的形式提供。最后,調(diào)用 writeZip 方法將更改寫回原文件或保存為一個(gè)新的 ZIP 文件。
最終輸出結(jié)果如下圖所示:
向壓縮文件中刪除指定內(nèi)容
使用 Adm-Zip 刪除 ZIP 文件中的內(nèi)容也非常直接。我們可以使用 deleteFile 方法來刪除 ZIP 文件中的指定文件。以下是如何使用 Adm-Zip 刪除 ZIP 文件中特定內(nèi)容的示例:
const AdmZip = require("adm-zip"); const zip = new AdmZip("./output.zip"); zip.deleteFile("moment.txt"); zip.writeZip("./output.zip"); console.log("文件已從ZIP中刪除。");
這段代碼首先加載一個(gè)已有的 ZIP 文件,然后使用 deleteFile 方法刪除指定的文件。這里,我們通過傳遞要刪除的文件名作為參數(shù)來指定哪個(gè)文件應(yīng)該被刪除。最后,通過調(diào)用 writeZip 方法將更改寫回原文件或保存為一個(gè)新的 ZIP 文件。
最終代碼的輸出結(jié)果如下圖所示:
如何對壓縮文件進(jìn)行解壓
使用 Adm-Zip 庫在 Node.js 中解壓 ZIP 文件同樣簡單直接。以下是步驟和代碼示例,展示如何使用 Adm-Zip 解壓 ZIP 文件:
const AdmZip = require("adm-zip"); // 指定ZIP文件的路徑 const zip = new AdmZip("./output.zip"); // 解壓到指定的目錄中,第二個(gè)參數(shù)為是否強(qiáng)制覆蓋 zip.extractAllTo("./moment", true); console.log("ZIP文件已成功解壓。");
最終代碼輸出的結(jié)果如下圖所示:
加密壓縮
創(chuàng)建加密的 ZIP 文件在 Node.js 中稍微復(fù)雜一些,因?yàn)?Adm-Zip 不直接支持創(chuàng)建加密的 ZIP 文件。對于需要直接創(chuàng)建支持密碼保護(hù)的 ZIP 文件的場景,可以考慮使用專門的命令行工具(如 7-Zip)通過 Node.js 的 child_process 模塊調(diào)用。
在 mac 中,首先需要我們安裝相對應(yīng)的工具,如下:
brew install p7zip
安裝完成之后,我們要在 node 中編寫如下代碼:
const { exec } = require("child_process"); const password = "moment"; // 替換為你的密碼 const inputFile = "./moment"; // 要加密的文件或文件夾路徑 const encryptedZip = "./moment.zip"; // 輸出的加密ZIP文件路徑 const command = `7z a -p${password} -tzip -mem=AES256 ${encryptedZip} ${inputFile}`; exec(command, (error, stdout, stderr) => { if (error) { console.error(`執(zhí)行的錯(cuò)誤: ${error}`); return; } console.log(`stdout: ${stdout}`); if (stderr) { console.error(`stderr: ${stderr}`); } });
在上面的 command 中,定義了一個(gè)將要執(zhí)行的命令字符串。命令使用了 7z(7-Zip 的命令行工具)來創(chuàng)建加密的 ZIP 文件。讓我們分解這個(gè)命令:
- 7z:調(diào)用 7-Zip 命令行工具。
- a:表示添加文件到壓縮文件中。
-p${password}
:設(shè)置密碼用于加密壓縮文件。${password}會被之前定義的 password 變量的值替換。-tzip
:指定壓縮文件的類型為 ZIP。- -mem=AES256:指定使用 AES-256 加密算法進(jìn)行加密。
${encryptedZip} ${inputFile}
:分別是創(chuàng)建的加密 ZIP 文件的路徑和要壓縮的文件或文件夾的路徑。這兩個(gè)占位符會被相應(yīng)的變量值替換。
上面代碼的執(zhí)行結(jié)果如下圖所示:
被我們壓縮成功了,且打開的時(shí)候需要密碼的,輸入密碼后解壓成功:
對加密文件進(jìn)行解壓
要使用 7z 命令實(shí)現(xiàn) ZIP 文件的解壓,特別是解壓一個(gè)使用密碼加密的 ZIP 文件,你可以在 Node.js 中使用類似的方法調(diào)用 7z 命令。
const { exec } = require("child_process"); const password = "moment"; // 用于解壓的密碼,應(yīng)與加密時(shí)相同 const zipFilePath = "./moment.zip"; // 加密的ZIP文件路徑 const outputDir = "./777"; // 解壓到的目錄路徑 const command = `7z x -p${password} -o"${outputDir}" "${zipFilePath}" -y`; exec(command, (error, stdout, stderr) => { if (error) { console.error(`執(zhí)行的錯(cuò)誤: ${error}`); return; } console.log(`stdout: ${stdout}`); if (stderr) { console.error(`stderr: ${stderr}`); } });
在上面的代碼中,我們解釋一下命令中的各個(gè)部分:
- 7z:調(diào)用 7-Zip 命令行工具。
- x:表示解壓縮操作。
- -ppassword:提供用于解壓的密碼,{password}:提供用于解壓的密碼,password:提供用于解壓的密碼,{password}會被替換為之前定義的密碼變量的值。
- -o"outputDir":指定解壓縮的輸出目錄,{outputDir}":指定解壓縮的輸出目錄,outputDir":指定解壓縮的輸出目錄,{outputDir}是目標(biāo)目錄路徑的變量。注意:路徑如果包含空格,應(yīng)該用引號""包圍起來。
- "${zipFilePath}":指向加密的 ZIP 文件的路徑,如果路徑包含空格,也應(yīng)該用引號""包圍。
- -y:自動回答所有提示為'是',例如覆蓋現(xiàn)有文件的提示。
使用這個(gè)命令,你可以解壓一個(gè)加密的 ZIP 文件到指定目錄,不需要人工干預(yù)過程中的任何提示。
最終代碼的允許結(jié)果如下圖所示:
總結(jié)
通過上面的案例我們基本已經(jīng)實(shí)現(xiàn)了一個(gè)壓縮文件中的基本功能了,我們可以將這些思想使用 electron 或者 tauri 編寫成一個(gè)桌面端,這樣我們就不用去安裝那些別人的軟件了。
到此這篇關(guān)于基于Nodejs實(shí)現(xiàn)文件壓縮和解壓功能的文章就介紹到這了,更多相關(guān)Nodejs文件壓縮和解壓內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深入理解Commonjs規(guī)范及Node模塊實(shí)現(xiàn)
本篇文章主要介紹了深入理解Commonjs規(guī)范及Node模塊實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05Node.js利用Net模塊實(shí)現(xiàn)多人命令行聊天室的方法
Node.js Net 模塊提供了一些用于底層的網(wǎng)絡(luò)通信的小工具,包含了創(chuàng)建服務(wù)器/客戶端的方法,下面這篇文章主要給大家介紹了Node.js利用Net模塊實(shí)現(xiàn)命令行多人聊天室的方法,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12node.js中的定時(shí)器nextTick()和setImmediate()區(qū)別分析
本文介紹了node.js中的定時(shí)器nextTick()和setImmediate()的區(qū)別分析,非常的不錯(cuò),這里推薦給大家。2014-11-11nodejs發(fā)布靜態(tài)https服務(wù)器步驟指南
這篇文章主要為大家介紹了nodejs發(fā)布靜態(tài)https服務(wù)器的步驟指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-02-02淺談如何通過node.js對數(shù)據(jù)進(jìn)行MD5加密
本篇文章將主要針對于在NODE.JS中如何對數(shù)據(jù)進(jìn)行MD5加密,MD5是一種常用的哈希算法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05