位置: IT常識(shí) - 正文
推薦整理分享【Node.js實(shí)戰(zhàn)】一文帶你開發(fā)博客項(xiàng)目之日志(文件讀寫、stream流、寫日志)(node.js in action),希望有所幫助,僅作參考,歡迎閱讀內(nèi)容。
文章相關(guān)熱門搜索詞:node.js入門教程,node.js入門教程,node.js 10實(shí)戰(zhàn),node.js in action,node-js,node js教程,node-js,node-js,內(nèi)容如對(duì)您有幫助,希望把文章鏈接給更多的朋友!
個(gè)人簡(jiǎn)介
👀個(gè)人主頁(yè): 前端雜貨鋪 🙋?♂?學(xué)習(xí)方向: 主攻前端方向,也會(huì)涉及到服務(wù)端 📃個(gè)人狀態(tài): 在校大學(xué)生一枚,已拿多個(gè)前端 offer(秋招) 🚀未來打算: 為中國(guó)的工業(yè)軟件事業(yè)效力n年 🥇推薦學(xué)習(xí):🍍前端面試寶典 🍉Vue2 🍋Vue3 🍓Vue2&Vue3項(xiàng)目實(shí)戰(zhàn) 🥝Node.js🍒Three.js 🌕個(gè)人推廣:每篇文章最下方都有加入方式,旨在交流學(xué)習(xí)&資源分享,快加入進(jìn)來吧
Node.js系列文章目錄內(nèi)容參考鏈接Node.js(一)初識(shí) Node.jsNode.js(二)Node.js——開發(fā)博客項(xiàng)目之接口Node.js(三)Node.js——一文帶你開發(fā)博客項(xiàng)目(使用假數(shù)據(jù)處理)Node.js(四)Node.js——開發(fā)博客項(xiàng)目之MySQL基礎(chǔ)Node.js(五)Node.js——開發(fā)博客項(xiàng)目之API對(duì)接MySQLNode.js(六)Node.js——開發(fā)博客項(xiàng)目之登錄(前置知識(shí))Node.js(七)Node.js——開發(fā)博客項(xiàng)目之登錄(對(duì)接完畢)Node.js(八)Node.js——開發(fā)開發(fā)博客項(xiàng)目之聯(lián)調(diào)文章目錄Node.js系列文章目錄一、前言二、文件的讀寫1、讀取文件2、寫入文件3、判斷文件是否存在三、stream 流1、IO 操作的性能瓶頸2、stream 流3、復(fù)制文件4、發(fā)起請(qǐng)求讀取文件四、寫日志五、寫在最后一、前言開發(fā)日志對(duì)整個(gè)項(xiàng)目可以起到備忘、記錄、總結(jié)等作用。以幫助開發(fā)或者運(yùn)維人員快速定位錯(cuò)誤位置,提出解決方案。
系統(tǒng)沒有日志,就等于人沒有眼睛(重要性可見一斑)第一,訪問日志 access log(server 端最重要的日志)第二,自定義日志(包括自定義事件、錯(cuò)誤記錄等)所以,日志的存在還是非常非常有必要的!
日志要放在文件中,可讀可寫~
node.js 文件操作,node.js stream(流 => 提升性能)日志功能開發(fā)和使用日志文件拆分,日志內(nèi)容分析二、文件的讀寫1、讀取文件接下來,我們先學(xué)習(xí)如何進(jìn)行文件的讀取…
創(chuàng)建 file-test 文件夾,文件夾下創(chuàng)建 test1.txt 文件 和 data.txt 文件
test1.txt
進(jìn)行文件讀取操作,讀取 data.txt 文本的內(nèi)容,并進(jìn)行輸出
const fs = require('fs')const path = require('path')// 獲取文件目錄 __dirname 表示當(dāng)前文件所在目錄const fileName = path.resolve(__dirname, 'data.txt')// 讀取文件內(nèi)容(異步的)fs.readFile(fileName, (err, data) => { if (err) { console.error(err) return } // data 是二進(jìn)制類型,需要轉(zhuǎn)成字符串類型 console.log(data.toString())})data.txt
這是我們?cè)谖谋局写鎯?chǔ)的一些信息
Hello這里是前端雜貨鋪感謝你的觀看Thanks2、寫入文件接下來,我們進(jìn)行文件的寫入操作(分為兩種:追加寫入和覆蓋寫入)
test1.js
const fs = require('fs')const path = require('path')// 獲取文件目錄 __dirname 表示當(dāng)前文件所在目錄const fileName = path.resolve(__dirname, 'data.txt')// 寫入文件const content = '哇咔咔,這是新寫入的內(nèi)容\n'// 寫入的方式(追加'a'/覆蓋'w')const opt = { flag: 'a' // 追加寫入用'a',覆蓋用 'w'}// 寫入文件(文件名,內(nèi)容,方式,錯(cuò)誤的回調(diào))fs.writeFile(fileName, content, opt, err => { if (err) { console.error(err) }})終端運(yùn)行 node test1.js
3、判斷文件是否存在接下來,我們來進(jìn)行判斷文件是否存在的操作
test1.js
const fs = require('fs')const path = require('path')// 獲取文件目錄 __dirname 表示當(dāng)前文件所在目錄const fileName = path.resolve(__dirname, 'data.txt')// 判斷文件是否存在fs.exists(fileName, (exist) => { console.log('exist', exist)})三、stream 流1、IO 操作的性能瓶頸IO 包括 “網(wǎng)絡(luò)IO” 和 “文件IO”相比于 CPU 計(jì)算和內(nèi)存讀寫,IO 的突出特點(diǎn)就是慢!我們需要在有限的硬件資源下提高 IO 的操作效率!!那么我們就要使用 stream 流(不是一下子全給,而是通過“小管子”一點(diǎn)點(diǎn)給…)
2、stream 流在 stream-test 文件夾下創(chuàng)建 test1.js 文件
test1.js
// 標(biāo)準(zhǔn)輸入輸出process.stdin.pipe(process.stdout)下面我們監(jiān)聽端口,通過 postman 進(jìn)行簡(jiǎn)單測(cè)試
test1.js
const http = require('http')const server = http.createServer((req, res) => { if (req.method === 'POST') { // 管道連接請(qǐng)求和響應(yīng) req.pipe(res) }})// 監(jiān)聽的端口 8000server.listen(8000)終端 node test1.js 啟動(dòng)它,之后去 postman 進(jìn)行測(cè)試
3、復(fù)制文件我們先創(chuàng)建 stream-test 文件,之后創(chuàng)建文本(原文本和復(fù)制的目標(biāo)文本,之后在 test1.js 中添加一些代碼),此時(shí) data.txt 文本有內(nèi)容,data-bak.txt 文本為空。
data.txt
這里是前端雜貨鋪當(dāng)前目標(biāo)如下:把 data.txt 文本里的內(nèi)容拷貝到 data-bak.txt 中test1.js
// 復(fù)制文件const fs = require('fs')const path = require('path')const fileName1 = path.resolve(__dirname, 'data.txt')const fileName2 = path.resolve(__dirname, 'data-bak.txt')// 讀取流const readStream = fs.createReadStream(fileName1)// 寫入流const writeStream = fs.createWriteStream(fileName2)// 管道連接readStream.pipe(writeStream)// 監(jiān)聽每一次讀取的內(nèi)容readStream.on('data', chunk => { console.log(chunk.toString())})// 監(jiān)聽拷貝完成readStream.on('end', () => { console.log('copy done')})4、發(fā)起請(qǐng)求讀取文件
發(fā)送一個(gè) GET 請(qǐng)求,讀取文本的內(nèi)容
test.js
const http = require('http')const fs = require('fs')const path = require('path')const fileName1 = path.resolve(__dirname, 'data.txt')const server = http.createServer((req, res) => { if (req.method === 'GET') { const readStream = fs.createReadStream(fileName1) // 將 res 作為 stream 的 dest readStream.pipe(res) }})// 監(jiān)聽的端口 8000server.listen(8000)終端 node test1.js 運(yùn)行,之后打開 8000 端口
四、寫日志我們首先改變一下我們的目錄結(jié)構(gòu)(新增如下文件)
logs 里面的文件用來存放寫入的日志(創(chuàng)建空文件就好),utils 里面的 log.js 文件用來編寫一些寫入日志的邏輯
log.js
首先我們引入所需模塊,封裝寫入流函數(shù),訪問我們所需的日志,進(jìn)行換行寫入
// 引入 fs 和 path 模塊const fs = require('fs')const path = require('path')// 寫日志function writeLog(writeStream, log) { // 關(guān)鍵代碼(每寫入一行日志換行一次) writeStream.write(log + '\n')}// 生成 write Stream(第二個(gè)水桶)function createWriteStream(fileName) { // 找到文件名 const fullFileName = path.join(__dirname, '../', '../', 'logs', fileName) // 創(chuàng)建寫入流(追加的方式) const writeStream = fs.createWriteStream(fullFileName, { flags: 'a' }) // 返回寫入的內(nèi)容 return writeStream}// 寫訪問日志const accessWriteStream = createWriteStream('access.log')// 參數(shù) log 為 app.js 中傳入的內(nèi)容function access(log) { writeLog(accessWriteStream, log)}module.exports = { access}之后更改 app.js 文件,調(diào)用 access 函數(shù)
app.js
我們先導(dǎo)入 access 進(jìn)來,之后進(jìn)行調(diào)用,傳進(jìn)所需的參數(shù),用來記錄 access log
const { access } = require('./src/utils/log')...const serverHandle = (req, res) => { // 記錄 access log access(`${req.method} -- ${req.url} -- ${req.headers['user-agent']} -- ${Date.now()}`) ......}之后,我們打開 http://localhost:8000/api/blog/list 端口,進(jìn)行三次刷新,查看 access.log 文件中日志的寫入
五、寫在最后至此,我們明白了 如何進(jìn)行文件讀寫,了解了 stream流 的原理及其基本使用,以及如何寫日志。 繼續(xù)跟進(jìn)學(xué)習(xí)吧!
后續(xù)會(huì)對(duì)該項(xiàng)目進(jìn)行多次重構(gòu)【多種框架(express,koa)和數(shù)據(jù)庫(kù)(mysql,sequelize,mongodb)】
如果你需要該項(xiàng)目的 源碼,請(qǐng)通過本篇文章最下面的方式 加入 進(jìn)來~~
上一篇:Electron-vue 系列之自動(dòng)更新與手動(dòng)更新(electron-vue官網(wǎng))
下一篇:HTML中關(guān)于邊框(border)的使用(html關(guān)于邊框的代碼)
網(wǎng)站地圖: 企業(yè)信息 工商信息 財(cái)稅知識(shí) 網(wǎng)絡(luò)常識(shí) 編程技術(shù)
友情鏈接: 武漢網(wǎng)站建設(shè)