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