欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nodejs使用archiver-zip-encrypted庫(kù)加密壓縮文件時(shí)報(bào)錯(cuò)(解決方案)

 更新時(shí)間:2019年11月18日 09:50:44   作者:By jacpy  
這篇文章主要介紹了Nodejs使用archiver-zip-encrypted庫(kù)加密壓縮文件時(shí)報(bào)錯(cuò),朋友朋友在測(cè)試過(guò)程中都出現(xiàn)過(guò)異常,下面小編把問(wèn)題過(guò)程分析腳本之家平臺(tái),需要的朋友可以參考下

前幾天在維護(hù)一個(gè)nodejs寫的命令行工具,要增加一個(gè)壓縮zip文件時(shí)加密碼功能。壓縮文件時(shí)使用了 archiver 庫(kù),加密碼使用了 archiver-zip-encrypted 庫(kù)。在windows系統(tǒng)上測(cè)試時(shí),發(fā)現(xiàn)會(huì)概率的出現(xiàn)以下異常:

events.js:174 
throw er; // Unhandled 'error' event 
^
Error: file data stream has unexpected number of bytes 
at ByteCounter. (
xxx\node_modules\yazl\index.js:162:99) 
at ByteCounter.emit (events.js:194:15) 
at endReadableNT (_stream_readable.js:1103:12) 
at process._tickCallback (internal/process/next_tick.js:63:19) 
Emitted 'error' event at: 
at ByteCounter. (xxx\node_modules\yazl\index.js:162:85) 
at ByteCounter.emit (events.js:194:15) 
at endReadableNT (_stream_readable.js:1103:12) 
at process._tickCallback (internal/process/next_t

我的本機(jī)環(huán)境是:

npm:6.9.0
node: v10.16.3

在另外一個(gè)同事的windows系統(tǒng)上測(cè)試,他那邊是上面異常必現(xiàn),對(duì)應(yīng)的node版本是v10.15。

具體使用的代碼不貼了,基本上是參照官方 demo 來(lái)寫的,壓縮完成最后調(diào)用代碼如下所示:

archive.finalize().then(() => {
  // 到這里認(rèn)為是壓縮完成,進(jìn)行后續(xù)處理,實(shí)際并沒有,參照后面分析
  anotherProcess();
}).catch(err => {
  // 壓縮出現(xiàn)異常處理...
});

出現(xiàn)異常后一一檢查代碼和官方demo不一樣的地方,并沒有發(fā)現(xiàn)什么異常之處,網(wǎng)上搜索也沒有發(fā)現(xiàn)這種異常記錄。由于剛接觸JS,不是很熟,就從問(wèn)題開始下手,找到出現(xiàn)問(wèn)題的代碼,開始調(diào)試。

錯(cuò)誤日志中提示是在 yzal/index.js 文件中發(fā)生異常,找到出現(xiàn)異常的代碼如下所示:

function pumpFileDataReadStream(self, entry, readStream) {
 var crc32Watcher = new Crc32Watcher();
 var uncompressedSizeCounter = new ByteCounter();
 var compressor = entry.compress ? new zlib.DeflateRaw() : new PassThrough();
 var compressedSizeCounter = new ByteCounter();
 readStream.pipe(crc32Watcher)
      .pipe(uncompressedSizeCounter)
      .pipe(compressor)
      .pipe(compressedSizeCounter)
      .pipe(self.outputStream, {end: false});
 compressedSizeCounter.on("end", function() {
  entry.crc32 = crc32Watcher.crc32;
  if (entry.uncompressedSize == null) {
   entry.uncompressedSize = uncompressedSizeCounter.byteCount;
  } else {
   // 異常從這里拋出來(lái)的
   if (entry.uncompressedSize !== uncompressedSizeCounter.byteCount) return self.emit("error", new Error("file data stream has unexpected number of bytes"));
  }
  entry.compressedSize = compressedSizeCounter.byteCount;
  self.outputStreamCursor += entry.compressedSize;
  writeToOutputStream(self, entry.getDataDescriptor());
  entry.state = Entry.FILE_DATA_DONE;
  pumpEntries(self);
 });
}

從上面代碼可以看出來(lái): uncompressedSizeCounter.byteCount 是從 pumpFileDataReadStream() 函數(shù) readStream 參數(shù)中獲取的屬性值,而 entry.uncompressedSize 也是函數(shù)的 entry 參數(shù)中獲取的屬性。接著找 pumpFileDataReadStream() 函數(shù)是從哪里調(diào)用的。

通過(guò)輸出日志得出 pumpFileDataReadStream() 函數(shù)是在以下面的代碼中被調(diào)用的:

ZipFile.prototype.addFile = function(realPath, metadataPath, options) {
 var self = this;
 metadataPath = validateMetadataPath(metadataPath, false);
 if (options == null) options = {};
 var entry = new Entry(metadataPath, false, options);
 self.entries.push(entry);
 fs.stat(realPath, function(err, stats) {
  if (err) return self.emit("error", err);
  if (!stats.isFile()) return self.emit("error", new Error("not a file: " + realPath));
  // 這里是文件的大小
  entry.uncompressedSize = stats.size;
  if (options.mtime == null) entry.setLastModDate(stats.mtime);
  if (options.mode == null) entry.setFileAttributesMode(stats.mode);
  entry.setFileDataPumpFunction(function() {
   // readStream在這里創(chuàng)建的
   var readStream = fs.createReadStream(realPath);
   entry.state = Entry.FILE_DATA_IN_PROGRESS;
   readStream.on("error", function(err) {
    self.emit("error", err);
   });
   // 在這里被調(diào)用
   pumpFileDataReadStream(self, entry, readStream);
  });
  pumpEntries(self);
 });
};

從上面代碼可以看出來(lái) entry.uncompressedSize 是stats.size,即文件的大小, readStream 是創(chuàng)建的文件流。但是在什么情況下兩者會(huì)不一樣呢?感覺只可能在文件還沒有讀取完,但是是什么原因?qū)е逻@種情況發(fā)生?由于對(duì)JS接觸的時(shí)間不長(zhǎng),沒有進(jìn)行深入分析。最后在拋出異常的上面一行用 console.log 將兩個(gè)屬性的大小值都輸出,代碼如下所示:

if (entry.uncompressedSize == null) {
   entry.uncompressedSize = uncompressedSizeCounter.byteCount;
} else {
 // 增加日志輸出
 console.log("entry size: " + entry.uncompressedSize + ", uncompressedSize: " + uncompressedSizeCounter.byteCount);
 if (entry.uncompressedSize !== uncompressedSizeCounter.byteCount) return self.emit("error", new Error("file data stream has unexpected number of bytes"));
}

在 archive.finalize() 時(shí)和 output 寫入流的 close 事件時(shí)(詳細(xì)參照官方的示例代碼),分別加上日志輸出,代碼如下所示:

archive.finalize().then(() => {
 // 到這里認(rèn)為是壓縮完成,進(jìn)行后續(xù)處理,實(shí)際并沒有,參照后面分析
 console.log("finalize");
 // anotherProcess();
}).catch(err => {
  // 壓縮出現(xiàn)異常
});
output.on('close', function() {
 console.log('close');
 // 這個(gè)業(yè)務(wù)函數(shù)與上面finalize函數(shù)中的是互斥,不會(huì)同時(shí)存在
 anotherProcess();
});

最后分別將 anotherProcess() 函數(shù)加到兩個(gè)異步回調(diào)中執(zhí)行,發(fā)現(xiàn)在 close 事件執(zhí)行時(shí),兩個(gè)size輸出的大小一致,都是文件的大小。而在 finalize 場(chǎng)景測(cè)試發(fā)現(xiàn) uncompressedSize 要小于文件的大小。最后將 anotherProcess() 函數(shù)放在 close 事件回調(diào)函數(shù)中執(zhí)行,問(wèn)題解決。

總結(jié)

以上所述是小編給大家介紹的Nodejs使用archiver-zip-encrypted庫(kù)加密壓縮文件時(shí)報(bào)錯(cuò),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

相關(guān)文章

  • Node.js中的HTTP模塊與URL模塊

    Node.js中的HTTP模塊與URL模塊

    這篇文章介紹了Node.js中的HTTP模塊與URL模塊,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • nodejs中模塊定義實(shí)例詳解

    nodejs中模塊定義實(shí)例詳解

    這篇文章主要介紹了nodejs中模塊定義方法,結(jié)合實(shí)例形式分析了nodejs模塊的原理、常見模塊及相應(yīng)的定義方法,需要的朋友可以參考下
    2017-03-03
  • package.json各個(gè)屬性說(shuō)明詳解

    package.json各個(gè)屬性說(shuō)明詳解

    這篇文章主要介紹了package.json各個(gè)屬性說(shuō)明詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • nodejs的HTML分析利器node-jquery用法淺析

    nodejs的HTML分析利器node-jquery用法淺析

    這篇文章主要介紹了nodejs的HTML分析利器node-jquery用法,簡(jiǎn)單分析了node-jquery的功能并結(jié)合實(shí)例說(shuō)明了node-jquery控制臺(tái)輸出信息的操作技巧,需要的朋友可以參考下
    2016-11-11
  • Nodejs alpine基礎(chǔ)之docker鏡像構(gòu)建

    Nodejs alpine基礎(chǔ)之docker鏡像構(gòu)建

    這篇文章主要為大家介紹了Nodejs alpine基礎(chǔ)之docker鏡像構(gòu)建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • node.js中的fs.lchown方法使用說(shuō)明

    node.js中的fs.lchown方法使用說(shuō)明

    這篇文章主要介紹了node.js中的fs.lchown方法使用說(shuō)明,本文介紹了fs.lchown的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Mongoose學(xué)習(xí)全面理解(推薦)

    Mongoose學(xué)習(xí)全面理解(推薦)

    本篇文章主要介紹了Mongoose全面理解,詳細(xì)的介紹了mongoose連接數(shù)據(jù)庫(kù),查找讀取數(shù)據(jù)和數(shù)據(jù)驗(yàn)證等,有興趣的可以了解一下。
    2017-01-01
  • 基于node.js express mvc輕量級(jí)框架實(shí)踐

    基于node.js express mvc輕量級(jí)框架實(shí)踐

    下面小編就為大家?guī)?lái)一篇基于node.js express mvc輕量級(jí)框架實(shí)踐。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • npm?install常見報(bào)錯(cuò)以及問(wèn)題詳解

    npm?install常見報(bào)錯(cuò)以及問(wèn)題詳解

    npm?install總是一言難盡,下面這篇文章主要給大家介紹了關(guān)于npm?install常見報(bào)錯(cuò)以及問(wèn)題的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • node.js基于dgram數(shù)據(jù)報(bào)模塊創(chuàng)建UDP服務(wù)器和客戶端操作示例

    node.js基于dgram數(shù)據(jù)報(bào)模塊創(chuàng)建UDP服務(wù)器和客戶端操作示例

    這篇文章主要介紹了node.js基于dgram數(shù)據(jù)報(bào)模塊創(chuàng)建UDP服務(wù)器和客戶端操作,結(jié)合實(shí)例形式分析了node.js使用dgram數(shù)據(jù)報(bào)模塊創(chuàng)建UDP服務(wù)器和客戶端,以及進(jìn)行UDP廣播、組播相關(guān)操作技巧,需要的朋友可以參考下
    2020-02-02

最新評(píng)論