一、前言
最近有這樣的一個需求,需要把兩個同名的.mtl文件和.obj文件打包成一個同名的.zip壓縮包。剛開始文件不多的時候,只有幾個,或者十幾個,甚至二三十個的時候,還能勉強接受手動修改,但是隨着項目的進展,手動壓縮是沒有效率且浪費時間的,於是就有了想用程序實現自動打包的想法。
二、使用jszip打包壓縮包
首先項目的前端是通過jszip進行解壓讀取的,既然它能解壓,自然也可以實現壓縮。上GitHub上找了關於zip的壓縮插件,還是發現jszip的star是排名第一的,不用用,有些過意不去啊。
開始我的步驟:
1、在Node.js項目里引入jszip包
npm install --save-dev jszip
2、jszip核心代碼
var fs = require('fs'); var path = require('path'); var JSZip = require('jszip'); var config = {
// 文件根目錄 dir:"C:/objs/ariport/" } /** * 把mtl文件和obj文件打包成zip壓縮包 * @param {} fileName 不帶文件后綴的文件名 * @param {} {delSource = false } = {} 是否刪除源文件 */ function toZipOfMtlObj (fileName, { delSource = false } = {}) { var zip = new JSZip(); var extArr = ['.mtl', '.obj']; extArr.forEach(ext => { let file = fileName + ext; let content = getFileContent(fileName + ext); zip.file(file, content); }) // 壓縮 zip.generateAsync({ // 壓縮類型選擇nodebuffer,在回調函數中會返回zip壓縮包的Buffer的值,再利用fs保存至本地 type: "nodebuffer", // 壓縮算法 compression: "DEFLATE", compressionOptions: { level: 9 } }).then(function (content) { let zip = fileName + '.zip'; // 寫入磁盤 fs.writeFile(getFullFileName(zip), content, function (err) { if (!err) { // 是否刪除源文件 if (delSource) { extArr.forEach(ext => { delFile(fileName + ext); }) } } else { console.log(zip + '壓縮失敗'); } }); }); } /** * 獲取文件內容 * @param {string} fileName 文件名 file.mtl */ function getFileContent (fileName) {
// 指定encoding會返回一個string,否則返回一個Buffer let content = fs.readFileSync(getFullFileName(fileName), { encoding: "utf-8" }); return content; } /** * 獲取完整文件路徑 * @param {string} fileName 文件名 file.mtl */ function getFullFileName (fileName) { return path.join(config.dir, fileName); } /** * 刪除文件 * @param {string} fileName 文件名 file.mtl */ function delFile (fileName) { fs.unlink(getFullFileName(fileName), function (err) { if (!!err) { console.log('刪除文件失敗:' + file); } }); }
第一步:聲明一個jszip壓縮對象
var zip = new JSZip();
第二步:往jszip壓縮對象添加文件
// jszip.file接收兩個參數,第一個參數是文件名,第二個參數是內容 zip.file('Building_North_001.mtl','這里是內容,可以是string,也可以是Buffer'); zip.file('Building_North_001.obj','這里是內容,可以是string,也可以是Buffer'); // jszip還可以添加文件夾,這里我就不做說明,可以參考官方文檔。
第三步:生成zip壓縮包內容的Buffer值,專門為Node.js使用
// 壓縮 zip.generateAsync({ // 壓縮類型選擇nodebuffer,在回調函數中會返回zip壓縮包的Buffer的值,再利用fs保存至本地 type: "nodebuffer", // 壓縮算法 compression: "DEFLATE", compressionOptions: { level: 9 } }).then(function (content) { let zip = 'Building_North_001.zip'; // 寫入磁盤 fs.writeFile('C:/objs/airport/' + zip , content, function (err) { if (!err) { // 寫入磁盤成功 console.log(zip + '壓縮成功'); } else { console.log(zip + '壓縮失敗'); } }); });
三、最后,總結
關於jszip壓縮部分就這么多,這僅僅只是簡單的一部分,更多的內容,可以訪問jszip的官方介紹。
在實現這個壓縮功能的過程中,也順便復習了Node.js中文件系統fs的使用:
1、同步讀取文件夾下的文件列表:fs.readdirSync(config.dir);
2、獲取一個文件的屬性:fs.statSync(filePath);
3、重命名:fs.rename(oldPath, newPath, function (err) {});
4、寫入文件:fs.writeFile(fullPath, content, function (err) {});
5、同步讀取文件內容,指定encoding會返回一個string,否則返回一個Buffer:fs.readFileSync(getFullFileName(fileName), { encoding: "utf-8" });
6、刪除一個文件:fs.unlink(fullPath, function (err) {});
學無止境,總結就這么多了。