溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么使用Node.js實(shí)現(xiàn)文件解壓縮

發(fā)布時(shí)間:2022-09-07 09:53:28 來(lái)源:億速云 閱讀:3078 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“怎么使用Node.js實(shí)現(xiàn)文件解壓縮”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“怎么使用Node.js實(shí)現(xiàn)文件解壓縮”文章能幫助大家解決問(wèn)題。

    compressing

    compressing 是一個(gè)使用起來(lái)方便、功能非常強(qiáng)大的node庫(kù),它可以對(duì)文件、文件夾進(jìn)行解壓或壓縮,支持tar、gzip、tgz、zip等多種格式。

    簡(jiǎn)單安裝之后 npm install compressing,以 zip 壓縮包為例

    解壓

    解壓比較簡(jiǎn)單,tar、gzip、zip 都是同個(gè) API

    const compressing = require('compressing');
    // 將壓縮包解壓到 test 文件夾中
    compressing.zip.uncompress('./test.zip','./test').then(() => {
    	console.log('解壓完成')
    }).catch(() => {
    	console.log('解壓失敗')
    })
    // 將壓縮包解壓到當(dāng)前文件夾中
    compressing.zip.uncompress('./test.zip','./')

    壓縮

    const compressing = require('compressing');
    // 壓縮一個(gè)文件
    compressing.zip.compressFile('E:/1.txt','E:/1.zip').then(() => {
    	console.log('壓縮完成')
    }).catch(() => {
    	console.log('壓縮失敗')
    })
    // 壓縮一個(gè)文件夾
    compressing.zip.compressDir('E:/test', 'E:/test.zip').then(func1).catch(func2);
    // 同時(shí)壓縮多個(gè)文件和文件夾,采用 stream 的方式
    const zipStream = new compressing.zip.Stream();
    zipStream.addEntry('./test');
    zipStream.addEntry('./1.txt');
    zipStream.pipe(fs.createWriteStream('./test1.zip')).on('finish', ()=>{
    	console.log('壓縮完成')
    }).on('error', ()=>{
    	console.log('壓縮失敗')
    })

    在使用compressing.zip.compressDir壓縮整個(gè)文件夾的時(shí)候,會(huì)把最外層的文件夾也一起壓縮,解壓出來(lái)又是一個(gè)完整的文件夾。但是我的需求時(shí)只想把這個(gè)文件夾下的所有文件打包,直接解壓出來(lái)得到零散的很多個(gè)文件。

    最初的想法呢是通過(guò) fs的API對(duì)文件夾進(jìn)行遍歷,用 addEntry 的方式打包,后來(lái)發(fā)現(xiàn)原來(lái)是可以設(shè)置參數(shù)的,只是文檔中沒(méi)有表現(xiàn)出來(lái),而且寫(xiě)著:usually you don't need it ,導(dǎo)致我走了很多彎路。

    后面在 addEntry 的接口文檔中看到了有個(gè) opt.ignoreBase 的參數(shù),才想到 compressDir 是不是也可以用。于是嘗試了一下,的確滿(mǎn)足了我的需求,含淚刪掉遍歷文件夾的代碼。

    compressing.zip.compressDir('E:/test', 'E:/test.zip', {
    	ignoreBase: true
    })

    基本上,一個(gè)解壓和壓縮的需求就可以完成了??善陀龅搅藗€(gè)問(wèn)題,在用 compressing 壓縮成一個(gè)zip包之后,在某個(gè)特殊的系統(tǒng)中,用系統(tǒng)自帶的解壓出來(lái),文件都變成文件夾了,比如 app.js 是個(gè)js文件,解壓后變成一個(gè)名為 app.js 的文件夾。這就很尷尬了。

    我嘗試了compressDiraddEntry的方式,最終得到的結(jié)果都一樣。于是乎,為了驗(yàn)證是這個(gè)系統(tǒng)本身解壓算法的問(wèn)題,我又找了另外一個(gè)壓縮庫(kù)。

    archiver

    archiver是一個(gè)在nodejs中能跨平臺(tái)實(shí)現(xiàn)打包功能的模塊,通過(guò) stream 的方式,可以打zip和tar包。如果連這個(gè)打包之后在這個(gè)系統(tǒng)中解壓出來(lái)的文件還是有問(wèn)題的話(huà),那我就可以認(rèn)為是這個(gè)系統(tǒng)的問(wèn)題,而不是我代碼的問(wèn)題。

    const output = fs.createWriteStream('./test.zip');
    const archive = archiver('zip', {zlib: {
    	level: 9 // 設(shè)置壓縮等級(jí)
    }});
    archive.pipe(output);
    archive.directory('./test', false); // 這里false參數(shù)和上面的ignoreBase為true效果一樣
    archive.finalize();	// 完成壓縮
    archive.on('end', () => {	// 壓縮結(jié)束時(shí)觸發(fā)
    	console.log('壓縮完成');
    });

    本來(lái)想證明是這個(gè)系統(tǒng)本身存在問(wèn)題,結(jié)果卻狠狠打臉了。用 archiver 壓縮后的 zip 包在這個(gè)系統(tǒng)中解壓出來(lái)是正常的文件,那么真相就是 compressing 的壓縮算法有點(diǎn)問(wèn)題,只不過(guò)這個(gè)問(wèn)題復(fù)現(xiàn)的場(chǎng)景很不一般,在正常的系統(tǒng)中都不會(huì)遇到。

    不過(guò)呢,我想了又想,現(xiàn)在也只能算是一比一打平,為了科學(xué)的嚴(yán)謹(jǐn)性,我決定再找一個(gè)壓縮庫(kù)進(jìn)行驗(yàn)證。

    adm-zip

    adm-zip 是一個(gè)支持zip壓縮和解壓縮的庫(kù),而我也只需要壓縮zip格式包,剛好可以滿(mǎn)足我的需求。

    壓縮

    const admzip = new AdmZip();
    // 壓縮文件夾
    admzip.addLocalFolder('./test');
    // 壓縮文件
    admzip.addLocalFile('./1.txt');
    admzip.writeZip('./test.zip');

    addLocalFolder 壓縮整個(gè)文件夾的時(shí)候,會(huì)把這個(gè)文件夾下的所有文件打包,直接解壓出來(lái)得到零散的很多個(gè)文件,效果和compressDir設(shè)置參數(shù)ignoreBase為true一樣。

    addLocalFolder 支持第二個(gè)參數(shù),可以將要壓縮的文件,壓縮進(jìn)壓縮包的某個(gè)路徑下。

    admzip.addLocalFolder('./test','aaa');
    admzip.addLocalFolder('./test','aaa/bbb');

    可以設(shè)置多級(jí)目錄,解壓出來(lái)后的文件就在這個(gè)目錄里。

    writeZip 是一個(gè)同步的方法,而上面兩個(gè)庫(kù)壓縮都是異步的。在使用 adm-zip 打包之后,驗(yàn)證出來(lái)的效果和 archiver 是一樣的,在那個(gè)特殊的系統(tǒng)上,解壓都沒(méi)有問(wèn)題。這就真的證明了 compressing 真的存在小問(wèn)題,不過(guò)在正常場(chǎng)景中應(yīng)該都可以忽略不計(jì)。

    解壓縮

    adm-zip 也支持解壓縮。

    const admzip = new AdmZip('./test.zip');
    admzip.extractAllTo('./test'); // 把整個(gè)壓縮包完全解壓到 test 目錄中

    除了解壓整個(gè)壓縮包,還支持單獨(dú)解壓某個(gè)文件

    const admzip = new AdmZip('./test.zip');
    const entry = zip.getEntry('1.txt');
    admzip.extractEntryTo(entry, './test2', true, true);

    extractEntryTo 支持4個(gè)參數(shù),第三個(gè)參數(shù)表示是否需要?jiǎng)?chuàng)建父文件夾,第四個(gè)參數(shù)表示是否要覆蓋。

    關(guān)于“怎么使用Node.js實(shí)現(xiàn)文件解壓縮”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI