目錄:
一、node.js介紹
二、node.js有哪些特點
三、下載安裝node.js,配置環境變量
四、node.js開發網站和傳統PHP等開發網站的區別
五、REPL介紹
六、helloworld程序
七、案例:輸出一個三角形
八、fs寫入文件和讀取文件
九、__dirname和__filename獲取正在執行的js文件的路徑
十、使用path模塊進行路徑拼接
十一、通過http模塊構建一個簡單的http服務程序
十二、Buffer
一、node.js介紹 <--返回目錄
1.1、node.js是什么
官網首頁總結:Node.js® 是一個基於 Chrome V8 引擎 的 JavaScript 運行時。
1)node.js是一個開發平台,就像java開發平台、.net開發平台、PHP開發平台、Apple開發平台一樣。
- 什么是開發平台:有對應的編程語言、有語言運行時、有能實現特定功能的API(SDK Software Development Kit)
2)node.js平台使用的編程語言是JavaScript。
3)node.js平台是基於Chrome V8 JavaScript 引擎構建。
1.2、node.js可以做什么
1)基於node.js可以開發控制台程序(命令行程序、CLI程序)、桌面應用程序(GUI,要借助node-webkit、electron等框架實現)、web應用程序(網站)
2)PHP開發技術棧:LAMP - Linux Apache MySQL PHP
3)node.js全棧開發技術棧:MEAN- MongoDB Express Angular Node.js
二、node.js有哪些特點 <--返回目錄
1)事件驅動:當事件被觸發,執行傳遞過去的回調函數
2)非阻塞I/O模型:當執行I/O操作時,不會阻塞線程
3)單線程
4)擁有世界最大的開源庫生態系統-npm
node.js在處理高並發、I/O密集場景性能優勢明顯。
- CPU密集:壓縮、解壓、加密、解密
- I/O密集:文件操作、網絡操作、數據庫操作
web常見場景:靜態資源讀取、數據庫操作、渲染頁面。
node.js的單線程:單線程只是針對主進程,I/O操作系統底層多線程調度。
三、下載安裝node.js,配置環境變量 <--返回目錄
node.js官方網站:https://nodejs.org/
中文網: http://nodejs.cn/
中文社區:https://cnodejs.org/
下載win 64為安裝包:node-v10.16.0-x64.msi,雙擊安裝
為了在任何目錄下都可以使用node和npm命令,將這兩個命令添加到環境變量path。我安裝node時默認就添加到了環境變量。
四、node.js開發網站和傳統PHP等開發網站的區別 <--返回目錄
1)傳統php、java、asp.net開發web程序需要web容器
2)node.js本身就是web服務器
- 接收用戶請求后,根據不同的請求直接做對應處理
- 把處理后的結果返回給瀏覽器
五、REPL介紹 <--返回目錄
1)REPL全稱Read Eval Print Loop交互式解釋器
- R 讀取,讀取用戶輸入,解析輸入js數據結構並儲存在內存中
- E 執行,執行輸入的數據結構
- P 打印,輸出結果
- L 循環,循環操作以上步驟直到用戶兩次按下Ctrl+c按鈕退出
2)在REPL中編寫程序,類似於瀏覽器開發人員工具中的控制台功能。
3)直接在控制台輸入node命令,進入REPL環境。
4)按兩次Ctrl+c 或者輸入 .exit ,退出REPL界面
六、helloworld程序 <--返回目錄
新建一個helloworld.js
var m = 10; var n = 20; function add(x, y) { return x + y; } console.log(m + "和"+ n + "相加,等於" + add(m,n));
在包含helloworld.js文件的目錄下,shift+右鍵,在此處打開命令窗口;輸入命令 node hel(tab補全),控制台會打印結果。
七、案例:輸出一個三角形 <--返回目錄
process模塊是全局模塊,直接使用;
for(var i = 0; i <10; i++) { for(var j = 0;j <=i; j++) { process.stdout.write("* "); } console.log(); }
八、fs寫入文件和讀取文件 <--返回目錄
process模塊是全局模塊,直接使用;fs不是全局模塊,要用require加載
fs寫入文件:
// 加載文件操作fs模塊 var fs = require("fs"); // 文件寫入 // fs.writeFile('文件路徑','數據','選項',function(){}); fs.writeFile('./a.txt','hello world', 'utf-8', (err) => { // 如果err===null,表示寫入文件成功 // 只要err不是null,就表示寫入文件失敗 if (err) { throw err; console.log("數據寫入失敗: " + err); } else { console.log("數據寫入成功"); } });
fs文件追加內容:
fs.appendFile('./test.txt', 'bbbb', 'utf8', err => { console.log('done') })
fs讀取文件:
// 加載文件操作fs模塊 var fs = require("fs"); // fs.ReadFile('文件路徑','選項',function(){}); // 文件路徑'a.txt'是相對於執行node命令的路徑 fs.readFile('./a.txt','utf-8',(err,data) => { if (err) { throw err; console.log("數據讀取失敗"); } else { console.log(data); } });
fs.stat() 判斷是文件還是文件夾
fs.stat('./a.js', (err, stats) => { if (err) { console.log('文件不存在'); // 一般可以用來判斷文件是否存在 return; }; console.log(stats.isFile()); console.log(stats.isDirectory()); console.log(stats); });
fs.rename() 重命名
fs.rename('./text', 'test.txt', err => { if(err) throw err; console.log('done!'); });
fs.unlink() 刪除
fs.unlink('./test.txt', err => {});
fs.readdir() 讀取文件夾內容
fs.readdir('../', (err, files) => { if (err) throw err; console.log(files); })
fs.mkdir() 創建目錄
fs.mkdir('test', err => {});
fs.watch() 監視文件或文件夾的變化
fs.watch('./', {recursive: true}, (eventType, filename) => { console.log(eventType, filename); });
fs同步的方法
const fs = require("fs"); // 同步的讀取 var data = fs.readFileSync("./test.txt", 'utf8'); console.log("文件讀取完成, data: ", data); //同步的寫入 fs.writeFileSync("./test.txt", '很好', 'utf8'); //同步的追加 fs.appendFileSync("./test.txt", '呵呵', 'utf8');
九、__dirname和__filename獲取正在執行的js文件的路徑 <--返回目錄
前面的程序都是在hello.js所在目錄執行node ./hello.js命令。如果進到c盤,執行node D:\hello.js命令,結果:
__dirname表示當前正在執行的js文件的所在目錄;__filename表示當前正在執行的js文件的完整路徑
//fs讀取文件 // 加載文件操作fs模塊 var fs = require("fs"); // fs.writeFile('文件路徑','選項',function(){}); // fs.readFile(__dirname+'\\a.txt','utf-8',(err,data) => { fs.readFile(__dirname+'/a.txt','utf-8',(err,data) => { if (err) { throw err; console.log("數據讀取失敗"); } else { console.log(data); } });
所以,"./hello.js"中./是相對於執行node命令的路徑,而不是相對於當前js文件的路徑。
__dirname和__filename不是全局的,但是為什么使用的時候不需要通過require引入:
( function ("__dirname", "__filename") { //fs讀取文件 // 加載文件操作fs模塊 var fs = require("fs"); // fs.writeFile('文件路徑','選項',function(){}); // fs.readFile(__dirname+'\\a.txt','utf-8',(err,data) => { fs.readFile(__dirname+'/a.txt','utf-8',(err,data) => { if (err) { throw err; console.log("數據讀取失敗"); } else { console.log(data); } }); } )("當前正在執行的js文件的所在目錄","當前正在執行的js文件的完整路徑");
總結:__dirname、__filename總是返回文件的絕對路徑;
process.cwd()總是返回執行node命令所在文件夾;
require()方法總是相對當前文件;
pahth.resolve('./')是執行node命令所在文件夾
十、使用path模塊進行路徑拼接 <--返回目錄
path會根據系統拼接成對應的路徑,windows下格式是 \a\b\c
var path = require('path'); var str = path.join('/foo','bar','baz/asdf'); console.log(path); process.stdout.write(str); // \foo\bar\baz\asdf
const path = require('path') // normalize: 將路徑解析成標准的格式 console.log(path.normalize('/usr/local//bin')) // \usr\local\bin console.log(path.normalize('/usr/local/../bin')) // \usr\\bin // resolve: 將相對路徑解析成絕對路徑 console.log(path.resolve('./')) // D:\當前文件所在目錄名 // basename: 取文件名, dirname: 文件夾, extname: 擴展名 const pathName1 = path.basename('c:/a/b.js') console.log(pathName1) // b.js const pathName2 = path.basename('c:\\a\\b.js') console.log(pathName2) // b.js const filePath = '/usr/local/bin/a.txt' console.log(path.basename(filePath)) // a.txt console.log(path.dirname(filePath)) // /usr/local/bin console.log(path.extname(filePath)) // .txt console.log('='.repeat(50)) // parse format const parseResult = path.parse(filePath) console.log(parseResult) // {root:'/', dir:'/usr/local/bin', base:'a.txt', ext:'.txt', name:'a'} // parseResult對象中dir和base優先級高,即有這個兩個屬性,其他屬性值忽略掉。因為有dir和base屬性就可以完全拼接出完整的文件名 console.log(path.format(parseResult)) // /usr/local/bin\a.txt
const path = require('path') // sep delimiter win32 posix console.log('當前系統下sep: ', path.sep) console.log('win sep:', path.win32.sep) console.log('posix sep', path.posix.sep) console.log('PATH: ', process.env.path) console.log('當前系統下delimiter: ', path.delimiter) // delimiter是PATH的分隔符 console.log('win delimiter: ', path.win32.delimiter) console.log('posix delimiter: ', path.posix.delimiter)
十一、通過http模塊構建一個簡單的http服務程序 <--返回目錄
第一步:在d:/hello.js寫代碼:
// 加載http模塊 var http = require("http"); // 創建一個http服務對象 var server = http.createServer(); // 監聽用戶的請求 server.on('request', function(req,res) { res.setHeader('content-type','text/html;charset=utf-8'); res.write('<h1>hello 您好!</h1>'); res.end();//結束響應 }); // 開啟服務 server.listen('8080', function() { console.log('服務器已經啟動。'); });
第二步:cmd窗口輸入node D:\hello.js運行程序
第三步:瀏覽器輸入http://localhost:8080。
十二、Buffer <--返回目錄
Buffer用於處理二進制數據流,類似數組,但是Buffer大小固定。
構造Buffer
console.log(Buffer.alloc(5)) // 默認0填充 console.log(Buffer.alloc(5, 1)) //0x1填充 console.log(Buffer.allocUnsafe(5)) // 保持原有數據 console.log(Buffer.from([1, 2, 3])) console.log(Buffer.from('test')) // 默認utf-8編碼 console.log(Buffer.from('test', 'base64'))
Buffer的byteLength()、isBuffer()、concat()方法
/* Buffer.byteLength() Buffer.isBuffer() Buffer.concat() */ console.log(Buffer.byteLength('test')) // 4 console.log(Buffer.byteLength('測試')) // 6, utf-8編碼 console.log(Buffer.isBuffer({})) // false console.log(Buffer.isBuffer(Buffer.from([1, 2, 3]))) // true const buf1 = Buffer.from('hello') const buf2 = Buffer.from('世界') const buf3 = Buffer.from('!') const buf = Buffer.concat([buf1, buf2]) console.log(buf.toString()) // hello世界!
buf.length、buf.toString([encoding])、buf.fill(value[, start, end])
const buf = Buffer.allocUnsafe(10) buf[2] = 0xff console.log(buf.length) console.log(buf) buf.fill(0xff) console.log(buf) const buf2 = Buffer.from('hello world') console.log(buf2.toString()) console.log(buf2.toString('base64'))
buf.equals()、buf.indexOf()
const buf1 = Buffer.from('test') const buf2 = Buffer.from('test') console.log(buf1.equals(buf2)) // 比較內容是否相同,true console.log(buf1.indexOf('te')) // 0 console.log(buf1.indexOf('abc')) // 找不到,返回-1
---