mapper文件cant resolve param_Nodejs 中基于 Stream 的多文件合并实现
本文先從一個(gè) Stream 的基本示例開始,有個(gè)初步認(rèn)識(shí),中間會(huì)講在 Stream 中什么時(shí)候會(huì)出現(xiàn)內(nèi)存泄漏,及如何避免最后基于 Nodejs 中的 Stream 實(shí)現(xiàn)一個(gè)多文件合并為一個(gè)文件的例子。
一個(gè)簡單的 Stream 操作
創(chuàng)建一個(gè)可讀流 readable 一個(gè)可寫流 writeable,通過管道 pipe 將可寫流綁定到可讀流,一個(gè)簡單的 Stream 操作就完成了。
const?fs?=?require('fs');const?readable?=?fs.createReadStream('./test1.txt');
const?writeable?=?fs.createWriteStream('./test2.txt');
readable.pipe(writeable);
看下 pipe 這個(gè)方法兩個(gè)參數(shù):
- destination:是一個(gè)可寫流對(duì)象,也就是一個(gè)數(shù)據(jù)寫入的目標(biāo)對(duì)象,例如,上面我們創(chuàng)建的 writeable 就是一個(gè)可寫流對(duì)象
- options:
- end:讀取結(jié)束時(shí)終止寫入流,默認(rèn)值是 true
默認(rèn)情況下我們是不需要手動(dòng)調(diào)用寫入流的 end 方法關(guān)閉的。
現(xiàn)在我們改一下,設(shè)置 end 為 false 寫入的目標(biāo)流將會(huì)一直處于打開狀態(tài), 此時(shí)就需要監(jiān)聽可讀流的 end 事件,結(jié)束之后手動(dòng)調(diào)用可寫流的 end 事件。
//?readable.pipe(writeable);readable.pipe(writeable,?{
??end:?false,
});
readable.on('end',?function()?{
??writeable.end('結(jié)束');
});
還需要注意一點(diǎn)如果可讀流期間發(fā)生什么錯(cuò)誤,則寫入的目標(biāo)流將不會(huì)關(guān)閉,例如:process.stderr 和 process.stdout 可寫流在 Nodejs 進(jìn)程退出前將永遠(yuǎn)不會(huì)關(guān)閉,所以需要監(jiān)聽錯(cuò)誤事件,手動(dòng)關(guān)閉可寫流,防止內(nèi)存泄漏。
Linux 下一切皆文件,為了測試,在創(chuàng)建可讀流時(shí),你可以不創(chuàng)建 test1.txt 文件,讓可讀流自動(dòng)觸發(fā) error 事件并且將 writeable 的 close 方法注釋掉,通過 linux 命令 ls -l /proc/${pid}/fd 查看 error 和非 error 前后的文件句柄變化。
readable.on('error',?function(err)?{??console.log('error',?err);
??//?writeable.close();
});
console.log(process.pid);?//?打印進(jìn)程?ID
setInterval(function(){},?5000)?//?讓程序不中斷,進(jìn)程不退出
以下為觸發(fā) error 錯(cuò)誤下 test2.txt 這個(gè)文件 fd 將會(huì)一直打開,除非進(jìn)程退出,所以重要的事情再說一遍,一定要做好錯(cuò)誤監(jiān)聽手動(dòng)關(guān)閉每個(gè)寫入流,以防止 “內(nèi)存泄漏”。
...l-wx------?1?root?root?64?Apr?10?15:47?19?->?/root/study/test2.txt
...
多個(gè)文件通過 Stream 合并為一個(gè)文件
上面講了 Stream 的基本使用,最后提到一點(diǎn)設(shè)置可讀流的 end 為 false 可保持寫入流一直處于打開狀態(tài)。如何將多個(gè)文件通過 Stream 合并為一個(gè)文件,也是通過這種方式,一開始可寫流處于打開狀態(tài),直到所有的可讀流結(jié)束,我們?cè)賹⒖蓪懥鹘o關(guān)閉。
- streamMerge 函數(shù)為入口函數(shù)
- streamMergeRecursive 函數(shù)遞歸調(diào)用合并文件
const?path?=?require('path');
/**
?*?Stream?合并
?*?@param?{?String?}?sourceFiles?源文件目錄名
?*?@param?{?String?}?targetFile?目標(biāo)文件
?*/
function?streamMerge(sourceFiles,?targetFile)?{
??const?scripts?=?fs.readdirSync(path.resolve(__dirname,?sourceFiles));?//?獲取源文件目錄下的所有文件
??const?fileWriteStream?=?fs.createWriteStream(path.resolve(__dirname,?targetFile));?//?創(chuàng)建一個(gè)可寫流
??streamMergeRecursive(scripts,?fileWriteStream);
}
/**
?*?Stream?合并的遞歸調(diào)用
?*?@param?{?Array?}?scripts
?*?@param?{?Stream?}?fileWriteStream
?*/
function?streamMergeRecursive(scripts=[],?fileWriteStream)?{
??//?遞歸到尾部情況判斷
??if?(!scripts.length)?{
????return?fileWriteStream.end("console.log('Stream?合并完成')");?//?最后關(guān)閉可寫流,防止內(nèi)存泄漏
??}
??const?currentFile?=?path.resolve(__dirname,?'scripts/',?scripts.shift());
??const?currentReadStream?=?fs.createReadStream(currentFile);?//?獲取當(dāng)前的可讀流
??currentReadStream.pipe(fileWriteStream,?{?end:?false?});
??currentReadStream.on('end',?function()?{
????streamMergeRecursive(scripts,?fileWriteStream);
??});
??currentReadStream.on('error',?function(error)?{?//?監(jiān)聽錯(cuò)誤事件,關(guān)閉可寫流,防止內(nèi)存泄漏
????console.error(error);
????fileWriteStream.close();
??});
}
streamMerge('./scripts',?'./script.js');
可以自行實(shí)踐下,代碼放在了 Github 點(diǎn)擊 nodejs/module/stream-merge?查看。
nodejs/module/stream-merge: https://github.com/Q-Angelo/project-training/tree/master/nodejs/module/stream-merge
敬請(qǐng)關(guān)注「Nodejs技術(shù)棧」微信公眾號(hào),獲取優(yōu)質(zhì)文章
▼往期精彩回顧▼Node.js?util.promisify 實(shí)現(xiàn)源碼解析深入 Nodejs 源碼探究 CPU 信息的獲取與利用率計(jì)算Nodejs 進(jìn)階:解答 Cluster 模塊的幾個(gè)疑問多維度分析 Express、Koa 之間的區(qū)別你需要了解的有關(guān) Node.js 的所有信息Node.js 服務(wù) Docker 容器化應(yīng)用實(shí)踐一文零基礎(chǔ)教你學(xué)會(huì) Docker 入門到實(shí)踐JavaScript 浮點(diǎn)數(shù)之迷:大數(shù)危機(jī)Node.js 是什么?我為什么選擇它?分享 10 道 Nodejs 進(jìn)程相關(guān)面試題不容錯(cuò)過的 Node.js 項(xiàng)目架構(gòu)Node.js 內(nèi)存管理和 V8 垃圾回收機(jī)制總結(jié)
以上是生活随笔為你收集整理的mapper文件cant resolve param_Nodejs 中基于 Stream 的多文件合并实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 8.0 集群_集群架构03·
- 下一篇: ora-01740: 标识符中缺失双引号