Node.js了解

目錄
  1. Hello World
  2. 創(chuàng)建第一個(gè)Node.js應(yīng)用
  3. REPL (調(diào)試Javascript)
  4. 回調(diào)函數(shù)
  5. 事件循環(huán)
  6. 函數(shù)
  7. 模塊系統(tǒng)
  8. 路由

少壯不努力刚盈,老大徒傷悲符衔。

本文為本人略讀官網(wǎng)文檔后的大略筆記,實(shí)在不適合他人閱讀栏妖。

前言

Node.js : 運(yùn)行在服務(wù)端的JavaScript

是一個(gè)事件驅(qū)動(dòng)I/O服務(wù)端JavaScript環(huán)境,基于Google的V8引擎奖恰。

安裝

安裝node
brew install node

查看當(dāng)前node版本
node -v

1. Hello World

創(chuàng)建test.js (內(nèi)容如下)

console.log("Hello World"); 

終端執(zhí)行 node test.js

輸出Hello World
效果圖
交互模式(終端輸入node)效果圖

2. 創(chuàng)建第一個(gè)Node.js應(yīng)用

Node.js應(yīng)用的組成部分

1. 引入required模塊
  使用require指令來(lái)載入Node.js模塊吊趾。

2. 創(chuàng)建服務(wù)器
  服務(wù)器監(jiān)聽客戶端請(qǐng)求。
  Apache瑟啃、Nginx等HTTP 服務(wù)器论泛。

3. 接收請(qǐng)求與響應(yīng)請(qǐng)求 
  客戶端可以使用瀏覽器或終端發(fā)送HTTP請(qǐng)求,服務(wù)器接收請(qǐng)求后返回響應(yīng)數(shù)據(jù)蛹屿。

步驟1: 引入required模塊

// 使用require指令載入http 模塊屁奏,并將實(shí)例化的HTTP賦值給變量http
var http = require("http");

步驟2: 創(chuàng)建服務(wù)器

創(chuàng)建 server.js文件

var http = require('http');

// 創(chuàng)建服務(wù)器
http.createServer(function (request, response) {
    // 發(fā)送 HTTP 頭部 
    // HTTP 狀態(tài)值: 200 : OK
    // 內(nèi)容類型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});

    // 發(fā)送響應(yīng)數(shù)據(jù) "Hello World"
    response.end('Hello World\n');
}).listen(8088);

// 終端打印如下信息
console.log('Server running at http://127.0.0.1:8088/');

終端運(yùn)行 node server.js

如果運(yùn)行出錯(cuò),可能是端口號(hào)沖突错负,換一個(gè)端口即可坟瓢。
運(yùn)行效果

3. REPL (調(diào)試Javascript)

REPL(Read Eval Print Loop:交互式解釋器)
一個(gè)電腦的環(huán)境,類似 Window 系統(tǒng)的終端或 Unix/Linux shell犹撒,我們可以在終端中輸入命令折联,并接收系統(tǒng)的響應(yīng)。

Node自帶了交互式解釋器识颊,可以執(zhí)行以下任務(wù):
    1. 讀取 
      讀取用戶輸入诚镰,解析輸入了Javascript 數(shù)據(jù)結(jié)構(gòu)并存儲(chǔ)在內(nèi)存中。
    2. 執(zhí)行 
      執(zhí)行輸入的數(shù)據(jù)結(jié)構(gòu)
    3. 打印
      輸出結(jié)果
    4. 循環(huán)
      循環(huán)操作以上步驟直到用戶兩次按下 ctrl-c 按鈕退出祥款。
退出當(dāng)前終端
    ctrl + c 清笨。

按下兩次 - 退出 Node REPL
    ctrl + c 。

退出 Node REPL
    ctrl + d - 

查看輸入的歷史命令
    向上/向下鍵 

補(bǔ)全當(dāng)前命令
    tab 鍵 

列出可使用命令
    .help  

退出多行表達(dá)式
    .break 

退出多行表達(dá)式
    .clear 

保存當(dāng)前的 Node REPL 會(huì)話到指定文件
    .save filename  

載入當(dāng)前 Node REPL 會(huì)話的文件內(nèi)容
    .load filename 

首先镰踏,在終端輸入node

可使用
  1. 表達(dá)式運(yùn)算
  2. 變量
  3. 多行語(yǔ)句
  4. _獲取上一個(gè)表達(dá)式的值
運(yùn)行效果

4. 回調(diào)函數(shù)

Node 所有 API 都支持回調(diào)函數(shù)

回調(diào)函數(shù)一般作為函數(shù)的最后一個(gè)參數(shù)出現(xiàn)
  function foo1(name, age, callback) { }
  function foo2(value, callback1, callback2) { }

例1 (阻塞)

創(chuàng)建content.txt文件

Hello World!
Hello cx,,,

創(chuàng)建main.js文件

var fs = require("fs");

var data = fs.readFileSync('content.txt');
console.log(data.toString());
console.log("程序執(zhí)行結(jié)束!");

終端執(zhí)行 node main.js

Hello World!
Hello cx,,,
程序執(zhí)行結(jié)束!

例2 (非阻塞)

創(chuàng)建content.txt文件

Hello World!
Hello cx,,,

創(chuàng)建main.js文件

var fs = require("fs");

fs.readFile('content.txt', function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});
console.log("程序執(zhí)行結(jié)束!");

終端執(zhí)行 node main.js

程序執(zhí)行結(jié)束!
Hello World!
Hello cx,,,

5. 事件循環(huán)

NOde.js是單進(jìn)程單線程應(yīng)用程序函筋,但V8引擎提供了異步執(zhí)行回調(diào)接口,可處理大量的并發(fā)奠伪,所以性能非常高跌帐。
幾乎所有API都支持回調(diào)函數(shù)。
幾乎所有事件機(jī)制都是通過(guò)觀察者模式實(shí)現(xiàn)的绊率。
第一步:導(dǎo)入事件模塊谨敛,創(chuàng)建eventEmitter 對(duì)象
第二步:綁定事件
    回調(diào)函數(shù)作為最后一個(gè)參數(shù)。
    err對(duì)象作為回調(diào)函數(shù)第一個(gè)參數(shù)滤否。
    當(dāng)添加新的監(jiān)聽器時(shí)脸狸,newListener 事件會(huì)觸發(fā)。
    當(dāng)監(jiān)聽器被移除時(shí),removeListener 事件被觸發(fā)炊甲。
第三步:觸發(fā)事件
    類似于觀察者模式泥彤,所有注冊(cè)在某一事件上的處理函數(shù)都相當(dāng)于觀察者。當(dāng)事件觸發(fā)時(shí)依次調(diào)用處理函數(shù)卿啡。

// 1
// 引入 events 模塊
var events = require('events');
// 創(chuàng)建 eventEmitter 對(duì)象
var eventEmitter = new events.EventEmitter();

// 2
// 綁定事件及事件的處理程序
eventEmitter.on('eventName', eventHandler);

// 3
// 觸發(fā)事件
eventEmitter.emit('eventName');

例1

創(chuàng)建test.js文件(內(nèi)容如下)
執(zhí)行node test.js 輸出:
  連接成功吟吝。
  數(shù)據(jù)接收成功。
  程序執(zhí)行完畢颈娜。
// 引入 events 模塊
var events = require('events');
// 創(chuàng)建 eventEmitter 對(duì)象(在實(shí)例化時(shí)發(fā)生錯(cuò)誤剑逃,會(huì)觸發(fā) error 事件)
var eventEmitter = new events.EventEmitter();
 
// 創(chuàng)建事件處理程序
var connectHandler = function connected() {
   console.log('連接成功。');
  
   // 觸發(fā) data_received 事件 
   eventEmitter.emit('data_received');
}
 
// 綁定 connection 事件處理程序
eventEmitter.on('connection', connectHandler);
 
// 使用匿名函數(shù)綁定 data_received 事件
eventEmitter.on('data_received', function(){
   console.log('數(shù)據(jù)接收成功官辽。');
});
 
// 觸發(fā) connection 事件 
eventEmitter.emit('connection');
 
console.log("程序執(zhí)行完畢蛹磺。");

例2(err:回調(diào)函數(shù)的第一個(gè)參數(shù))

============== input.txt ==============
Hello World!
Hello cx,,,

============== test.js ==============
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
   if (err){
      console.log(err.stack);
      return;
   }
   console.log(data.toString());
});
console.log("程序執(zhí)行完畢");

============== node test.js ==============
程序執(zhí)行完畢
Hello World!
Hello cx,,,
==============刪除input.txt node test.js ==============
程序執(zhí)行完畢
Error: ENOENT: no such file or directory, open 'input.txt'

例3

輸出:
  listener1 arg1 參數(shù) arg2 參數(shù)
  listener2 arg1 參數(shù) arg2 參數(shù)
//event.js 文件
var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.on('someEvent', function(arg1, arg2) { 
    console.log('listener1', arg1, arg2); 
}); 
emitter.on('someEvent', function(arg1, arg2) { 
    console.log('listener2', arg1, arg2); 
}); 
emitter.emit('someEvent', 'arg1 參數(shù)', 'arg2 參數(shù)'); 
  1. EventEmitter

多數(shù)情況下不會(huì)直接使用 EventEmitter,而是在對(duì)象中繼承它同仆。包括 fs萤捆、net、 http 在內(nèi)的乓梨,只要是支持事件響應(yīng)的核心模塊都是 EventEmitter 的子類鳖轰。

通過(guò)require("events");導(dǎo)入events模塊清酥。
events模塊只提供了一個(gè)對(duì)象扶镀,就是events.EventEmitter。
EventEmitter的核心就是對(duì)事件觸發(fā)與事件監(jiān)聽器功能進(jìn)行封裝焰轻。
EventEmitter的每個(gè)事件由一個(gè)事件名和若干個(gè)參數(shù)組成臭觉。事件名是一個(gè)字符串。

Node.js 所有的異步 I/O 操作在完成時(shí)都會(huì)發(fā)送一個(gè)事件到事件隊(duì)列辱志。
Node.js 里面的許多對(duì)象都會(huì)分發(fā)事件:
  一個(gè) net.Server 對(duì)象會(huì)在每次有新連接時(shí)觸發(fā)一個(gè)事件
  一個(gè) fs.readStream 對(duì)象會(huì)在文件被打開的時(shí)候觸發(fā)一個(gè)事件蝠筑。 

所有這些產(chǎn)生事件的對(duì)象都是 events.EventEmitter 的實(shí)例。
方法名 描述
addListener(event, listener) 為指定事件添加一個(gè)監(jiān)聽器(添加到監(jiān)聽器數(shù)組的尾部)揩懒。
on(event, listener) 為指定事件注冊(cè)一個(gè)監(jiān)聽器(接受一個(gè)字符串 event 和一個(gè)回調(diào)函數(shù))什乙。 server.on('connection', function (stream) { console.log('someone connected!'); });
once(event, listener) 為指定事件注冊(cè)一個(gè)單次監(jiān)聽器(即監(jiān)聽器最多只會(huì)觸發(fā)一次,觸發(fā)后立刻解除該監(jiān)聽器)已球。 server.once('connection', function (stream) { console.log('Ah, we have our first user!'); });
removeListener(event, listener) 移除指定事件的某個(gè)監(jiān)聽器臣镣,監(jiān)聽器必須是該事件已經(jīng)注冊(cè)過(guò)的監(jiān)聽器。它接受兩個(gè)參數(shù)智亮,第一個(gè)是事件名稱忆某,第二個(gè)是回調(diào)函數(shù)名稱。 var callback = function(stream) { console.log('someone connected!'); }; server.on('connection', callback); server.removeListener('connection', callback);
removeAllListeners([event]) 移除所有事件的所有監(jiān)聽器阔蛉, 如果指定事件弃舒,則移除指定事件的所有監(jiān)聽器。
setMaxListeners(n) 默認(rèn)情況下状原, EventEmitters添加的監(jiān)聽器超過(guò) 10 個(gè)就會(huì)輸出警告信息聋呢。 setMaxListeners 函數(shù)用于提高監(jiān)聽器的默認(rèn)限制的數(shù)量苗踪。
listeners(event) 返回指定事件的監(jiān)聽器數(shù)組。
emit(event, [arg1], [arg2], [...]) 按監(jiān)聽器的順序執(zhí)行執(zhí)行每個(gè)監(jiān)聽器削锰,如果事件有注冊(cè)監(jiān)聽返回 true徒探,否則返回 false。
listenerCount(emitter, event) 類方法喂窟。返回指定事件的監(jiān)聽器數(shù)量测暗。 events.EventEmitter.listenerCount(emitter, eventName) //已廢棄,不推薦 events.emitter.listenerCount(eventName) //推薦
事件 描述
newListener event - 字符串磨澡,事件名稱碗啄。listener - 處理事件函數(shù)。該事件在添加新監(jiān)聽器時(shí)被觸發(fā)稳摄。
removeListener event - 字符串稚字,事件名稱伞鲫。listener - 處理事件函數(shù)湾盒。從指定監(jiān)聽器數(shù)組中刪除一個(gè)監(jiān)聽器憾儒。需要注意的是热幔,此操作將會(huì)改變處于被刪監(jiān)聽器之后的那些監(jiān)聽器的索引磺平。
error 事件 在遇到 異常的時(shí)候通常會(huì)觸發(fā) error 事件刽虹。如果沒(méi)有響 應(yīng)的監(jiān)聽器饶火,Node.js 會(huì)把它當(dāng)作異常米愿,退出程序并輸出錯(cuò)誤信息减噪。一般要為會(huì)觸發(fā) error 事件的對(duì)象設(shè)置監(jiān)聽器短绸,避免遇到錯(cuò)誤后整個(gè)程序崩潰。 var events = require('events'); var emitter = new events.EventEmitter(); emitter.emit('error');

例1

輸出

2 個(gè)監(jiān)聽器監(jiān)聽連接事件筹裕。
監(jiān)聽器 listener1 執(zhí)行醋闭。
監(jiān)聽器 listener2 執(zhí)行。
listener1 不再受監(jiān)聽朝卒。
監(jiān)聽器 listener2 執(zhí)行证逻。
1 個(gè)監(jiān)聽器監(jiān)聽連接事件。
程序執(zhí)行完畢抗斤。 
var events = require('events');
var eventEmitter = new events.EventEmitter();

// 監(jiān)聽器 #1
var listener1 = function listener1() {
   console.log('監(jiān)聽器 listener1 執(zhí)行囚企。');
}

// 監(jiān)聽器 #2
var listener2 = function listener2() {
  console.log('監(jiān)聽器 listener2 執(zhí)行。');
}

// 綁定 connection 事件豪治,處理函數(shù)為 listener1 
eventEmitter.addListener('connection', listener1);

// 綁定 connection 事件洞拨,處理函數(shù)為 listener2
eventEmitter.on('connection', listener2);

var eventListeners = eventEmitter.listenerCount('connection');
console.log(eventListeners + " 個(gè)監(jiān)聽器監(jiān)聽連接事件。");

// 處理 connection 事件 
eventEmitter.emit('connection');

// 移除監(jiān)綁定的 listener1 函數(shù)
eventEmitter.removeListener('connection', listener1);
console.log("listener1 不再受監(jiān)聽负拟。");

// 觸發(fā)連接事件
eventEmitter.emit('connection');

eventListeners = eventEmitter.listenerCount('connection');
console.log(eventListeners + " 個(gè)監(jiān)聽器監(jiān)聽連接事件烦衣。");

console.log("程序執(zhí)行完畢。");
 大多數(shù)時(shí)候我們不會(huì)直接使用 EventEmitter,而是在對(duì)象中繼承它花吟。包括 fs秸歧、net、 http 在內(nèi)的衅澈,只要是支持事件響應(yīng)的核心模塊都是 EventEmitter 的子類键菱。

為什么要這樣做呢?原因有兩點(diǎn):
首先今布,具有某個(gè)實(shí)體功能的對(duì)象實(shí)現(xiàn)事件符合語(yǔ)義经备, 事件的監(jiān)聽和發(fā)生應(yīng)該是一個(gè)對(duì)象的方法。
其次 JavaScript 的對(duì)象機(jī)制是基于原型的部默,支持 部分多重繼承侵蒙,繼承 EventEmitter 不會(huì)打亂對(duì)象原有的繼承關(guān)系。

6. 函數(shù)

函數(shù)作參

在JavaScript中傅蹂,一個(gè)函數(shù)可以作為另一個(gè)函數(shù)的參數(shù)纷闺。

function say(word) {
  console.log(word);
}
function execute(someFunction, value) {
  someFunction(value);
}
execute(say, "Hello");

匿名函數(shù)

function execute(someFunction, value) {
  someFunction(value);
}

execute(function(word){ console.log(word) }, "Hello");

http.createServer方法就是傳入了一個(gè)匿名函數(shù)

var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);
==================等價(jià)
function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}
http.createServer(onRequest).listen(8888);

7. 模塊系統(tǒng)

模塊是Node.js 應(yīng)用程序的基本組成部分。
文件和模塊是一一對(duì)應(yīng)的份蝴,即:一個(gè) Node.js 文件就是一個(gè)模塊犁功。這個(gè)文件可以是js代碼、JSON 婚夫、編譯過(guò)的C/C++ 擴(kuò)展浸卦。

Node.js提供了exports、require兩個(gè)對(duì)象请敦,分別用于導(dǎo)出镐躲、導(dǎo)入。

exports 
  暴露屬性和方法
module.exports
  暴露對(duì)象
require 方法中的文件查找策略

Node.js存在4類模塊(原生模塊和3種文件模塊)

原生模塊
    http侍筛、fs、path等撒穷。
相對(duì)路徑的文件模塊
    ./mod或../mod匣椰。
絕對(duì)路徑的文件模塊
    /pathtomodule/mod。
非原生模塊的文件模塊
    mod端礼。

在路徑 Y 下執(zhí)行 require(X) 語(yǔ)句執(zhí)行順序

1. 如果 X 是內(nèi)置模塊
   a. 返回內(nèi)置模塊
   b. 停止執(zhí)行
2. 如果 X 以 '/' 開頭
   a. 設(shè)置 Y 為文件根路徑
3. 如果 X 以 './' 或 '/' or '../' 開頭
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
4. LOAD_NODE_MODULES(X, dirname(Y))
5. 拋出異常 "not found"

LOAD_AS_FILE(X)
1. 如果 X 是一個(gè)文件, 將 X 作為 JavaScript 文本載入并停止執(zhí)行禽笑。
2. 如果 X.js 是一個(gè)文件, 將 X.js 作為 JavaScript 文本載入并停止執(zhí)行。
3. 如果 X.json 是一個(gè)文件, 解析 X.json 為 JavaScript 對(duì)象并停止執(zhí)行蛤奥。
4. 如果 X.node 是一個(gè)文件, 將 X.node 作為二進(jìn)制插件載入并停止執(zhí)行佳镜。

LOAD_INDEX(X)
1. 如果 X/index.js 是一個(gè)文件,  將 X/index.js 作為 JavaScript 文本載入并停止執(zhí)行。
2. 如果 X/index.json 是一個(gè)文件, 解析 X/index.json 為 JavaScript 對(duì)象并停止執(zhí)行凡桥。
3. 如果 X/index.node 是一個(gè)文件,  將 X/index.node 作為二進(jìn)制插件載入并停止執(zhí)行蟀伸。

LOAD_AS_DIRECTORY(X)
1. 如果 X/package.json 是一個(gè)文件,
   a. 解析 X/package.json, 并查找 "main" 字段。
   b. let M = X + (json main 字段)
   c. LOAD_AS_FILE(M)
   d. LOAD_INDEX(M)
2. LOAD_INDEX(X)

LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. LOAD_AS_FILE(DIR/X)
   b. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
   a. if PARTS[I] = "node_modules" CONTINUE
   b. DIR = path join(PARTS[0 .. I] + "node_modules")
   c. DIRS = DIRS + DIR
   d. let I = I - 1
5. return DIRS

例1(創(chuàng)建模塊)

================ hello.js ================
// 導(dǎo)出world
exports.world = function() {
  console.log('Hello World');
}
================ test.js ================
// ./ 為當(dāng)前目錄,node.js 默認(rèn)后綴為 js
var hello = require('./hello');
hello.world();

例2(當(dāng)只導(dǎo)出一個(gè)對(duì)象時(shí))

module.exports = function() {
  // ...
}


如:http模塊
var http = require("http");
http.createServer(...);
================  hello.js ================
//hello.js 
function Hello() { 
    var name; 
    this.setName = function(thyName) { 
        name = thyName; 
    }; 
    this.sayHello = function() { 
        console.log('Hello ' + name); 
    }; 
}; 
module.exports = Hello;
================  main.js ================
//main.js 
var Hello = require('./hello'); 
hello = new Hello(); 
hello.setName('BYVoid'); 
hello.sayHello(); 

8. 路由

屏幕快照 2020-04-03 11.09.49.png

. 工具 模塊

  1. OS 模塊(系統(tǒng)操作函數(shù))
引入

var os = require("os")
函數(shù) 說(shuō)明
os.tmpdir() 返回操作系統(tǒng)的默認(rèn)臨時(shí)文件夾啊掏。
os.endianness() 返回 CPU 的字節(jié)序蠢络,可能的是 "BE" 或 "LE"。
os.hostname() 返回操作系統(tǒng)的主機(jī)名迟蜜。
os.type() 返回操作系統(tǒng)名
os.platform() 返回編譯時(shí)的操作系統(tǒng)名
os.arch() 返回操作系統(tǒng) CPU 架構(gòu)刹孔,可能的值有 "x64"、"arm" 和 "ia32"娜睛。
os.release() 返回操作系統(tǒng)的發(fā)行版本髓霞。
os.uptime() 返回操作系統(tǒng)運(yùn)行的時(shí)間,以秒為單位畦戒。
os.loadavg() 返回一個(gè)包含 1酸茴、5、15 分鐘平均負(fù)載的數(shù)組兢交。
os.totalmem() 返回系統(tǒng)內(nèi)存總量薪捍,單位為字節(jié)。
os.freemem() 返回操作系統(tǒng)空閑內(nèi)存量配喳,單位是字節(jié)酪穿。
os.cpus() 返回一個(gè)對(duì)象數(shù)組,包含所安裝的每個(gè) CPU/內(nèi)核的信息:型號(hào)晴裹、速度(單位 MHz)被济、時(shí)間(一個(gè)包含 user、nice涧团、sys只磷、idle 和 irq 所使用 CPU/內(nèi)核毫秒數(shù)的對(duì)象)。
os.networkInterfaces() 獲得網(wǎng)絡(luò)接口列表泌绣。
屬性 說(shuō)明
os.EOL 定義了操作系統(tǒng)的行尾符的常量

例1 (test.js)

var os = require("os");

// CPU 的字節(jié)序
console.log('endianness : ' + os.endianness());

// 操作系統(tǒng)名
console.log('type : ' + os.type());

// 操作系統(tǒng)名
console.log('platform : ' + os.platform());

// 系統(tǒng)內(nèi)存總量
console.log('total memory : ' + os.totalmem() + " bytes.");

// 操作系統(tǒng)空閑內(nèi)存量
console.log('free memory : ' + os.freemem() + " bytes.");
node test.js輸出

endianness : LE
type : Darwin
platform : darwin
total memory : 17179869184 bytes.
free memory : 562544640 bytes.
  1. Path 模塊 (處理文件路徑的小工具)
引入

var path = require("path")
函數(shù) 說(shuō)明
path.normalize(p) 規(guī)范化路徑钮追,注意'..' 和 '.'。
path.join([path1][, path2][, ...]) 用于連接路徑阿迈。該方法的主要用途在于元媚,會(huì)正確使用當(dāng)前系統(tǒng)的路徑分隔符,Unix系統(tǒng)是"/"苗沧,Windows系統(tǒng)是""刊棕。
path.resolve([from ...], to) 將 to 參數(shù)解析為絕對(duì)路徑,給定的路徑的序列是從右往左被處理的待逞,后面每個(gè) path 被依次解析甥角,直到構(gòu)造完成一個(gè)絕對(duì)路徑。 例如识樱,給定的路徑片段的序列為:/foo嗤无、/bar震束、baz,則調(diào)用 path.resolve('/foo', '/bar', 'baz') 會(huì)返回 /bar/baz翁巍。
path.isAbsolute(path) 判斷參數(shù) path 是否是絕對(duì)路徑驴一。
path.relative(from, to) 用于將絕對(duì)路徑轉(zhuǎn)為相對(duì)路徑,返回從 from 到 to 的相對(duì)路徑(基于當(dāng)前工作目錄)灶壶。
path.dirname(p) 返回路徑中代表文件夾的部分肝断,同 Unix 的dirname 命令類似。
path.basename(p[, ext]) 返回路徑中的最后一部分驰凛。同 Unix 命令 bashname 類似胸懈。
path.extname(p) 返回路徑中文件的后綴名,即路徑中最后一個(gè)'.'之后的部分恰响。如果一個(gè)路徑中并不包含'.'或該路徑只包含一個(gè)'.' 且這個(gè)'.'為路徑的第一個(gè)字符趣钱,則此命令返回空字符串。
path.parse(pathString) 返回路徑字符串的對(duì)象胚宦。
path.format(pathObject) 從對(duì)象中返回路徑字符串首有,和 path.parse 相反。
屬性 說(shuō)明
path.sep 平臺(tái)的文件路徑分隔符枢劝,'\' 或 '/'井联。
path.delimiter 平臺(tái)的分隔符, ; or ':'.
path.posix 提供上述 path 的方法,不過(guò)總是以 posix 兼容的方式交互您旁。
path.win32 提供上述 path 的方法烙常,不過(guò)總是以 win32 兼容的方式交互。
path.resolve([from ...], to)   例:

// 返回: '/foo/bar/baz'    
path.resolve('/foo/bar', './baz');  
// 返回: '/tmp/file'  
path.resolve('/foo/bar', '/tmp/file/');  
// 如果當(dāng)前工作目錄為 /home/myself/node鹤盒,則返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');  
path.relative(from, to)

在 Linux 上:
path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
// 返回: '../../impl/bbb'

在 Windows 上:
path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb');
// 返回: '..\\..\\impl\\bbb'

例1(test.js)

var path = require("path");

// 格式化路徑
console.log('normalization : ' + path.normalize('/test/test1//2slashes/1slash/tab/..'));

// 連接路徑
console.log('joint path : ' + path.join('/test', 'test1', '2slashes/1slash', 'tab', '..'));

// 轉(zhuǎn)換為絕對(duì)路徑
console.log('resolve : ' + path.resolve('main.js'));

// 路徑中文件的后綴名
console.log('ext name : ' + path.extname('main.js'));
ode test.js輸出

normalization : /test/test1/2slashes/1slash
joint path : /test/test1/2slashes/1slash
resolve : /Users/cx/Desktop/nodejs/main.js
ext name : .js
  1. Net 模塊(用于底層的網(wǎng)絡(luò)通信的小工具蚕脏,包含了創(chuàng)建服務(wù)器/客戶端的方法)
引入

var net = require("net")
函數(shù) 說(shuō)明
net.createServer([options][, connectionListener]) 創(chuàng)建一個(gè) TCP 服務(wù)器。參數(shù) connectionListener 自動(dòng)給 'connection' 事件創(chuàng)建監(jiān)聽器侦锯。
net.connect(options[, connectionListener]) 返回一個(gè)新的 'net.Socket'驼鞭,并連接到指定的地址和端口。當(dāng) socket 建立的時(shí)候率触,將會(huì)觸發(fā) 'connect' 事件终议。
net.createConnection(options[, connectionListener]) 創(chuàng)建一個(gè)到端口 port 和 主機(jī) host的 TCP 連接。 host 默認(rèn)為 'localhost'葱蝗。
net.connect(port[, host][, connectListener]) 創(chuàng)建一個(gè)端口為 port 和主機(jī)為 host的 TCP 連接 。host 默認(rèn)為 'localhost'细燎。參數(shù) connectListener 將會(huì)作為監(jiān)聽器添加到 'connect' 事件两曼。返回 'net.Socket'。
net.createConnection(port[, host][, connectListener]) 創(chuàng)建一個(gè)端口為 port 和主機(jī)為 host的 TCP 連接 玻驻。host 默認(rèn)為 'localhost'悼凑。參數(shù) connectListener 將會(huì)作為監(jiān)聽器添加到 'connect' 事件偿枕。返回 'net.Socket'。
net.connect(path[, connectListener]) 創(chuàng)建連接到 path 的 unix socket 户辫。參數(shù) connectListener 將會(huì)作為監(jiān)聽器添加到 'connect' 事件上渐夸。返回 'net.Socket'。
net.createConnection(path[, connectListener]) 創(chuàng)建連接到 path 的 unix socket 渔欢。參數(shù) connectListener 將會(huì)作為監(jiān)聽器添加到 'connect' 事件墓塌。返回 'net.Socket'。
net.isIP(input) 檢測(cè)輸入的是否為 IP 地址奥额。 IPV4 返回 4苫幢, IPV6 返回 6,其他情況返回 0垫挨。
net.isIPv4(input) 如果輸入的地址為 IPV4韩肝, 返回 true,否則返回 false九榔。
net.isIPv6(input) 如果輸入的地址為 IPV6哀峻, 返回 true,否則返回 false哲泊。

》》》net.Server
通常用于創(chuàng)建一個(gè) TCP 或本地服務(wù)器

函數(shù) 說(shuō)明
erver.listen(port[, host][, backlog][, callback]) 監(jiān)聽指定端口 port 和 主機(jī) host ac連接剩蟀。 默認(rèn)情況下 host 接受任何 IPv4 地址(INADDR_ANY)的直接連接。端口 port 為 0 時(shí)攻旦,則會(huì)分配一個(gè)隨機(jī)端口喻旷。
server.listen(path[, callback]) 通過(guò)指定 path 的連接,啟動(dòng)一個(gè)本地 socket 服務(wù)器牢屋。
server.listen(handle[, callback]) 通過(guò)指定句柄連接且预。
server.listen(options[, callback]) options 的屬性:端口 port, 主機(jī) host, 和 backlog, 以及可選參數(shù) callback 函數(shù), 他們?cè)谝黄鹫{(diào)用server.listen(port, [host], [backlog], [callback])。還有烙无,參數(shù) path 可以用來(lái)指定 UNIX socket锋谐。
server.close([callback]) 服務(wù)器停止接收新的連接,保持現(xiàn)有連接截酷。這是異步函數(shù)涮拗,當(dāng)所有連接結(jié)束的時(shí)候服務(wù)器會(huì)關(guān)閉,并會(huì)觸發(fā) 'close' 事件迂苛。
server.address() 操作系統(tǒng)返回綁定的地址三热,協(xié)議族名和服務(wù)器端口。
server.unref() 如果這是事件系統(tǒng)中唯一一個(gè)活動(dòng)的服務(wù)器三幻,調(diào)用 unref 將允許程序退出就漾。
server.ref() 與 unref 相反,如果這是唯一的服務(wù)器念搬,在之前被 unref 了的服務(wù)器上調(diào)用 ref 將不會(huì)讓程序退出(默認(rèn)行為)抑堡。如果服務(wù)器已經(jīng)被 ref摆出,則再次調(diào)用 ref 并不會(huì)產(chǎn)生影響。
server.getConnections(callback) 異步獲取服務(wù)器當(dāng)前活躍連接的數(shù)量首妖。當(dāng) socket 發(fā)送給子進(jìn)程后才有效偎漫;回調(diào)函數(shù)有 2 個(gè)參數(shù) err 和 count。
事件 說(shuō)明
listening 當(dāng)服務(wù)器調(diào)用 server.listen 綁定后會(huì)觸發(fā)有缆。
connection 當(dāng)新連接創(chuàng)建后會(huì)被觸發(fā)象踊。socket 是 net.Socket實(shí)例。
close 服務(wù)器關(guān)閉時(shí)會(huì)觸發(fā)妒貌。注意通危,如果存在連接,這個(gè)事件不會(huì)被觸發(fā)直到所有的連接關(guān)閉灌曙。
error 發(fā)生錯(cuò)誤時(shí)觸發(fā)菊碟。'close' 事件將被下列事件直接調(diào)用。

》》》net.Socket
net.Socket對(duì)象是 TCP 或 UNIX Socket 的抽象在刺。
net.Socket 實(shí)例實(shí)現(xiàn)了一個(gè)雙工流接口逆害。
他們可以在用戶創(chuàng)建客戶端(使用 connect())時(shí)使用, 或者由 Node 創(chuàng)建它們,并通過(guò) connection 服務(wù)器事件傳遞給用戶蚣驼。

方法 說(shuō)明
new net.Socket([options]) 構(gòu)造一個(gè)新的 socket 對(duì)象魄幕。
socket.connect(port[, host][, connectListener]) 指定端口 port 和 主機(jī) host,創(chuàng)建 socket 連接 颖杏。參數(shù) host 默認(rèn)為 localhost纯陨。通常情況不需要使用 net.createConnection 打開 socket。只有你實(shí)現(xiàn)了自己的 socket 時(shí)才會(huì)用到留储。
socket.connect(path[, connectListener]) 打開指定路徑的 unix socket翼抠。通常情況不需要使用 net.createConnection 打開 socket。只有你實(shí)現(xiàn)了自己的 socket 時(shí)才會(huì)用到获讳。
socket.setEncoding([encoding]) 設(shè)置編碼
socket.write(data[, encoding][, callback]) 在 socket 上發(fā)送數(shù)據(jù)阴颖。第二個(gè)參數(shù)指定了字符串的編碼,默認(rèn)是 UTF8 編碼丐膝。
socket.end([data][, encoding]) 半關(guān)閉 socket量愧。例如,它發(fā)送一個(gè) FIN 包帅矗≠怂啵可能服務(wù)器仍在發(fā)送數(shù)據(jù)。
socket.destroy() 確保沒(méi)有 I/O 活動(dòng)在這個(gè)套接字上浑此。只有在錯(cuò)誤發(fā)生情況下才需要软棺。(處理錯(cuò)誤等等)。
socket.pause() 暫停讀取數(shù)據(jù)尤勋。就是說(shuō)喘落,不會(huì)再觸發(fā) data 事件。對(duì)于控制上傳非常有用最冰。
socket.resume() 調(diào)用 pause() 后想恢復(fù)讀取數(shù)據(jù)瘦棋。
socket.setTimeout(timeout[, callback]) socket 閑置時(shí)間超過(guò) timeout 毫秒后 ,將 socket 設(shè)置為超時(shí)暖哨。
socket.setNoDelay([noDelay]) 禁用納格(Nagle)算法赌朋。默認(rèn)情況下 TCP 連接使用納格算法,在發(fā)送前他們會(huì)緩沖數(shù)據(jù)篇裁。將 noDelay 設(shè)置為 true 將會(huì)在調(diào)用 socket.write() 時(shí)立即發(fā)送數(shù)據(jù)沛慢。noDelay 默認(rèn)值為 true。
socket.setKeepAlive([enable][, initialDelay] 禁用/啟用長(zhǎng)連接功能达布,并在發(fā)送第一個(gè)在閑置 socket 上的長(zhǎng)連接 probe 之前团甲,可選地設(shè)定初始延時(shí)。默認(rèn)為 false黍聂。 設(shè)定 initialDelay (毫秒)躺苦,來(lái)設(shè)定收到的最后一個(gè)數(shù)據(jù)包和第一個(gè)長(zhǎng)連接probe之間的延時(shí)。將 initialDelay 設(shè)為0产还,將會(huì)保留默認(rèn)(或者之前)的值匹厘。默認(rèn)值為0.
socket.address() 操作系統(tǒng)返回綁定的地址,協(xié)議族名和服務(wù)器端口脐区。返回的對(duì)象有 3 個(gè)屬性愈诚,比如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }。
socket.unref() 如果這是事件系統(tǒng)中唯一一個(gè)活動(dòng)的服務(wù)器牛隅,調(diào)用 unref 將允許程序退出炕柔。如果服務(wù)器已被 unref,則再次調(diào)用 unref 并不會(huì)產(chǎn)生影響倔叼。
socket.ref() 與 unref 相反汗唱,如果這是唯一的服務(wù)器,在之前被 unref 了的服務(wù)器上調(diào)用 ref 將不會(huì)讓程序退出(默認(rèn)行為)丈攒。如果服務(wù)器已經(jīng)被 ref哩罪,則再次調(diào)用 ref 并不會(huì)產(chǎn)生影響。
屬性 說(shuō)明
socket.bufferSize 該屬性顯示了要寫入緩沖區(qū)的字節(jié)數(shù)巡验。
socket.remoteAddress 遠(yuǎn)程的 IP 地址字符串括堤,例如:'74.125.127.100' or '2001:4860:a005::68'。
socket.remoteFamily 遠(yuǎn)程IP協(xié)議族字符串胁黑,比如 'IPv4' or 'IPv6'涩盾。
socket.remotePort 遠(yuǎn)程端口,數(shù)字表示捕捂,例如:80 or 21瑟枫。
socket.localAddress 網(wǎng)絡(luò)連接綁定的本地接口 遠(yuǎn)程客戶端正在連接的本地 IP 地址斗搞,字符串表示。例如慷妙,如果你在監(jiān)聽'0.0.0.0'而客戶端連接在'192.168.1.1'僻焚,這個(gè)值就會(huì)是 '192.168.1.1'。
socket.localPort 本地端口地址膝擂,數(shù)字表示虑啤。例如:80 or 21。
socket.bytesRead 接收到得字節(jié)數(shù)架馋。
socket.bytesWritten 發(fā)送的字節(jié)數(shù)狞山。
事件 說(shuō)明
ookup 在解析域名后,但在連接前叉寂,觸發(fā)這個(gè)事件萍启。對(duì) UNIX sokcet 不適用。
connect 成功建立 socket 連接時(shí)觸發(fā)办绝。
data 當(dāng)接收到數(shù)據(jù)時(shí)觸發(fā)伊约。
end 當(dāng) socket 另一端發(fā)送 FIN 包時(shí),觸發(fā)該事件孕蝉。
timeout 當(dāng) socket 空閑超時(shí)時(shí)觸發(fā)屡律,僅是表明 socket 已經(jīng)空閑。用戶必須手動(dòng)關(guān)閉連接降淮。
drain 當(dāng)寫緩存為空得時(shí)候觸發(fā)超埋。可用來(lái)控制上傳佳鳖。
error 錯(cuò)誤發(fā)生時(shí)觸發(fā)霍殴。
close 當(dāng) socket 完全關(guān)閉時(shí)觸發(fā)。參數(shù) had_error 是布爾值系吩,它表示是否因?yàn)閭鬏斿e(cuò)誤導(dǎo)致 socket 關(guān)閉来庭。

例1

============== server.js  ===============
var net = require('net');
var server = net.createServer(function(connection) { 
   console.log('client connected');
   connection.on('end', function() {
      console.log('客戶端關(guān)閉連接');
   });
   connection.write('Hello World!\r\n');
   connection.pipe(connection);
});
server.listen(8088, function() { 
  console.log('server is listening');
});


============== client.js  ===============
var net = require('net');
var client = net.connect({port: 8088}, function() {
   console.log('連接到服務(wù)器!');  
});
client.on('data', function(data) {
   console.log(data.toString());
   client.end();
});
client.on('end', function() { 
   console.log('斷開與服務(wù)器的連接');
});

============== 在兩個(gè)終端下分別執(zhí)行 node server.js穿挨、node client.js  ===============
服務(wù)端輸出
server is listening
client connected
客戶端關(guān)閉連接


客戶端輸出
  連接到服務(wù)器月弛!
  Hello World!

  斷開與服務(wù)器的連接
  1. DNS 模塊 (解析域名)
引入


var dns = require("dns")
函數(shù) 說(shuō)明
dns.lookup(hostname[, options], callback) 將域名(比如 'runoob.com')解析為第一條找到的記錄 A (IPV4)或 AAAA(IPV6)。參數(shù) options可以是一個(gè)對(duì)象或整數(shù)科盛。如果沒(méi)有提供 options帽衙,IP v4 和 v6 地址都可以。如果 options 是整數(shù)贞绵,則必須是 4 或 6厉萝。
dns.lookupService(address, port, callback) 使用 getnameinfo 解析傳入的地址和端口為域名和服務(wù)。
dns.resolve(hostname[, rrtype], callback) 將一個(gè)域名(如 'runoob.com')解析為一個(gè) rrtype 指定記錄類型的數(shù)組。
dns.resolve4(hostname, callback) 和 dns.resolve() 類似, 僅能查詢 IPv4 (A 記錄)谴垫。 addresses IPv4 地址數(shù)組 (比如章母,['74.125.79.104', '74.125.79.105', '74.125.79.106'])。
dns.resolve6(hostname, callback) 和 dns.resolve4() 類似弹渔, 僅能查詢 IPv6( AAAA 查詢)
dns.resolveMx(hostname, callback) 和 dns.resolve() 類似, 僅能查詢郵件交換(MX 記錄)胳施。
dns.resolveTxt(hostname, callback) 和 dns.resolve() 類似, 僅能進(jìn)行文本查詢 (TXT 記錄)。 addresses 是 2-d 文本記錄數(shù)組肢专。(比如,[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ])焦辅。 每個(gè)子數(shù)組包含一條記錄的 TXT 塊博杖。根據(jù)使用情況可以連接在一起,也可單獨(dú)使用筷登。
dns.resolveSrv(hostname, callback) 和 dns.resolve() 類似, 僅能進(jìn)行服務(wù)記錄查詢 (SRV 記錄)剃根。 addresses 是 hostname可用的 SRV 記錄數(shù)組。 SRV 記錄屬性有優(yōu)先級(jí)(priority)前方,權(quán)重(weight), 端口(port), 和名字(name) (比如狈醉,[{'priority': 10, 'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...])。
dns.resolveSoa(hostname, callback) 和 dns.resolve() 類似, 僅能查詢權(quán)威記錄(SOA 記錄)惠险。
dns.resolveNs(hostname, callback) 和 dns.resolve() 類似, 僅能進(jìn)行域名服務(wù)器記錄查詢(NS 記錄)苗傅。 addresses 是域名服務(wù)器記錄數(shù)組(hostname 可以使用) (比如, ['ns1.example.com', 'ns2.example.com'])。
dns.resolveCname(hostname, callback) 和 dns.resolve() 類似, 僅能進(jìn)行別名記錄查詢 (CNAME記錄)班巩。addresses 是對(duì) hostname 可用的別名記錄數(shù)組 (比如渣慕,, ['bar.example.com'])。
dns.reverse(ip, callback) 反向解析 IP 地址抱慌,指向該 IP 地址的域名數(shù)組逊桦。
dns.getServers() 返回一個(gè)用于當(dāng)前解析的 IP 地址數(shù)組的字符串。
dns.setServers(servers) 指定一組 IP 地址作為解析服務(wù)器抑进。
dns.resolve() 方法中有效的 rrtypes值:
    'A' IPV4 地址, 默認(rèn)
    'AAAA' IPV6 地址
    'MX' 郵件交換記錄
    'TXT' text 記錄
    'SRV' SRV 記錄
    'PTR' 用來(lái)反向 IP 查找
    'NS' 域名服務(wù)器記錄
    'CNAME' 別名記錄
    'SOA' 授權(quán)記錄的初始值
每次 DNS 查詢都可能返回以下錯(cuò)誤碼:

    dns.NODATA: 無(wú)數(shù)據(jù)響應(yīng)强经。
    dns.FORMERR: 查詢格式錯(cuò)誤。
    dns.SERVFAIL: 常規(guī)失敗寺渗。
    dns.NOTFOUND: 沒(méi)有找到域名匿情。
    dns.NOTIMP: 未實(shí)現(xiàn)請(qǐng)求的操作。
    dns.REFUSED: 拒絕查詢户秤。
    dns.BADQUERY: 查詢格式錯(cuò)誤码秉。
    dns.BADNAME: 域名格式錯(cuò)誤。
    dns.BADFAMILY: 地址協(xié)議不支持鸡号。
    dns.BADRESP: 回復(fù)格式錯(cuò)誤转砖。
    dns.CONNREFUSED: 無(wú)法連接到 DNS 服務(wù)器。
    dns.TIMEOUT: 連接 DNS 服務(wù)器超時(shí)。
    dns.EOF: 文件末端府蔗。
    dns.FILE: 讀文件錯(cuò)誤晋控。
    dns.NOMEM: 內(nèi)存溢出。
    dns.DESTRUCTION: 通道被摧毀姓赤。
    dns.BADSTR: 字符串格式錯(cuò)誤赡译。
    dns.BADFLAGS: 非法標(biāo)識(shí)符。
    dns.NONAME: 所給主機(jī)不是數(shù)字不铆。
    dns.BADHINTS: 非法HINTS標(biāo)識(shí)符蝌焚。
    dns.NOTINITIALIZED: c c-ares 庫(kù)尚未初始化。
    dns.LOADIPHLPAPI: 加載 iphlpapi.dll 出錯(cuò)誓斥。
    dns.ADDRGETNETWORKPARAMS: 無(wú)法找到 GetNetworkParams 函數(shù)只洒。
    dns.CANCELLED: 取消 DNS 查詢。

例1(test.js)

var dns = require('dns');

dns.lookup('www.github.com', function onLookup(err, address, family) {
   console.log('ip 地址:', address);
   dns.reverse(address, function (err, hostnames) {
   if (err) {
      console.log(err.stack);
   }

   console.log('反向解析 ' + address + ': ' + JSON.stringify(hostnames));
});  
});
node test.js輸出

ip 地址: 13.250.177.223
反向解析 13.250.177.223: ["ec2-13-250-177-223.ap-southeast-1.compute.amazonaws.com"]
  1. Domain 模塊 (捕捉處理try catch無(wú)法捕捉的異常)
引入

var domain = require("domain")
Domain 模塊分為
    1. 隱式綁定
      把在domain上下文中定義的變量劳坑,自動(dòng)綁定到domain對(duì)象
    2. 顯式綁定
      把不是在domain上下文中定義的變量毕谴,以代碼的方式綁定到domain對(duì)象

把處理多個(gè)不同的IO的操作作為一個(gè)組。注冊(cè)事件和回調(diào)到domain距芬,當(dāng)發(fā)生一個(gè)錯(cuò)誤事件或拋出一個(gè)錯(cuò)誤時(shí)涝开,domain對(duì)象會(huì)被通知,不會(huì)丟失上下文環(huán)境框仔,也不導(dǎo)致程序錯(cuò)誤立即退出舀武,與process.on('uncaughtException')不同
函數(shù) 說(shuō)明
domain.run(function) 在域的上下文運(yùn)行提供的函數(shù),隱式的綁定了所有的事件分發(fā)器存和,計(jì)時(shí)器和底層請(qǐng)求奕剃。
domain.add(emitter) 顯式的增加事件
domain.remove(emitter) 刪除事件。
domain.bind(callback) 返回的函數(shù)是一個(gè)對(duì)于所提供的回調(diào)函數(shù)的包裝函數(shù)捐腿。當(dāng)調(diào)用這個(gè)返回的函數(shù)時(shí)纵朋,所有被拋出的錯(cuò)誤都會(huì)被導(dǎo)向到這個(gè)域的 error 事件。
domain.intercept(callback) 和 domain.bind(callback) 類似茄袖。除了捕捉被拋出的錯(cuò)誤外操软,它還會(huì)攔截 Error 對(duì)象作為參數(shù)傳遞到這個(gè)函數(shù)。
domain.enter() 進(jìn)入一個(gè)異步調(diào)用的上下文宪祥,綁定到domain聂薪。
domain.exit() 退出當(dāng)前的domain,切換到不同的鏈的異步調(diào)用的上下文中蝗羊。對(duì)應(yīng)domain.enter()藏澳。
domain.dispose() 釋放一個(gè)domain對(duì)象,讓node進(jìn)程回收這部分資源耀找。
domain.create() 返回一個(gè)domain對(duì)象翔悠。
屬性 說(shuō)明
domain.members 已加入domain對(duì)象的域定時(shí)器和事件發(fā)射器的數(shù)組业崖。

例1(test.js)

var EventEmitter = require("events").EventEmitter;
var domain = require("domain");

var emitter1 = new EventEmitter();
// 創(chuàng)建域
var domain1 = domain.create();
domain1.on('error', function(err){
   console.log("domain1 處理這個(gè)錯(cuò)誤 ("+err.message+")");
});

// 顯式綁定
domain1.add(emitter1);
emitter1.on('error',function(err){
   console.log("監(jiān)聽器處理此錯(cuò)誤 ("+err.message+")");
});

emitter1.emit('error',new Error('通過(guò)監(jiān)聽器來(lái)處理'));
emitter1.removeAllListeners('error');
emitter1.emit('error',new Error('通過(guò) domain1 處理'));

var domain2 = domain.create();
domain2.on('error', function(err){
   console.log("domain2 處理這個(gè)錯(cuò)誤 ("+err.message+")");
});
// 隱式綁定
domain2.run(function(){
   var emitter2 = new EventEmitter();
   emitter2.emit('error',new Error('通過(guò) domain2 處理'));   
});

domain1.remove(emitter1);
emitter1.emit('error', new Error('轉(zhuǎn)換為異常,系統(tǒng)將崩潰!'));
node test.js輸出

監(jiān)聽器處理此錯(cuò)誤 (通過(guò)監(jiān)聽器來(lái)處理)
domain1 處理這個(gè)錯(cuò)誤 (通過(guò) domain1 處理)
domain2 處理這個(gè)錯(cuò)誤 (通過(guò) domain2 處理)
events.js:298
      throw er; // Unhandled 'error' event
      ^

Error: 轉(zhuǎn)換為異常蓄愁,系統(tǒng)將崩潰!
    at Object.<anonymous> (/Users/cx/Desktop/nodejs/client.js:40:24)
    at Module._compile (internal/modules/cjs/loader.js:1151:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
    at Module.load (internal/modules/cjs/loader.js:1000:32)
    at Function.Module._load (internal/modules/cjs/loader.js:899:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47
Emitted 'error' event at:
    at Object.<anonymous> (/Users/cx/Desktop/nodejs/client.js:40:10)
    at Module._compile (internal/modules/cjs/loader.js:1151:30)
    [... lines matching original stack trace ...]
    at internal/main/run_main_module.js:17:47
  1. util 模塊(Node.js核心)常用函數(shù)
引入

const util = require('util');

將 async 異步函數(shù)(或者一個(gè)返回值為 Promise 的函數(shù))轉(zhuǎn)換成遵循異常優(yōu)先的回調(diào)風(fēng)格的函數(shù)

// (err, value) => ... 回調(diào),作為最后一個(gè)參數(shù)
// 在回調(diào)函數(shù)中双炕,第一個(gè)參數(shù)為拒絕的原因(如果 Promise 解決,則為 null)撮抓,第二個(gè)參數(shù)則是解決的值妇斤。
util.callbackify(original)
例1

const util = require('util');

async function fn() {
  return 'hello world';
}
const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
  if (err) throw err;
  console.log(ret);
});


輸出
hello world
例2

function fn() {
  return Promise.reject(null);
}
const callbackFunction = util.callbackify(fn);

callbackFunction((err, ret) => {
  // 當(dāng) Promise 被以 `null` 拒絕時(shí),它被包裝為 Error 并且原始值存儲(chǔ)在 `reason` 中丹拯。
  err && err.hasOwnProperty('reason') && err.reason === null;  // true
});

實(shí)現(xiàn)對(duì)象間原型繼承的函數(shù)

util.inherits(constructor, superConstructor)

JavaScript 的面向?qū)ο筇匦允腔谠偷恼境c常見的基于類的不同。JavaScript 沒(méi)有提供對(duì)象繼承的語(yǔ)言級(jí)別特性咽笼,而是通過(guò)原型復(fù)制來(lái)實(shí)現(xiàn)的顷编。
例

============= test.js =============
var util = require('util'); 
function Base() { 
    this.name = 'cx'; 
    this.base = 2000; 
    this.sayHello = function() { 
    console.log('Hello ' + this.name); 
    }; 
} 
Base.prototype.showName = function() { 
    console.log(this.name);
}; 
function Sub() { 
    this.name = 'sub'; 
} 
util.inherits(Sub, Base); 
var objBase = new Base(); 
objBase.showName(); 
objBase.sayHello(); 
console.log(objBase); 
var objSub = new Sub(); 
objSub.showName(); 
//objSub.sayHello(); 
console.log(objSub); 
=============終端輸出=============
cx
Hello cx
Base { name: 'cx', base: 2000, sayHello: [Function (anonymous)] }
sub
Sub { name: 'sub' }

=============注意=============
Sub 僅僅繼承了Base 在原型中定義的函數(shù),而構(gòu)造函數(shù)內(nèi)部創(chuàng)造的 base 屬 性和 sayHello 函數(shù)都沒(méi)有被 Sub 繼承剑刑。
在原型中定義的屬性不會(huì)被 console.log 作 為對(duì)象的屬性輸出。

將任意對(duì)象轉(zhuǎn)換為字符串

// object 要轉(zhuǎn)換的對(duì)象
// showHidden 是否顯示隱藏信息
// depth 最大遞歸的層數(shù)双肤,默認(rèn)2層施掏,null則表示不限遞歸層數(shù)完整遍歷
// colors 以 ANSI 顏色編碼,在終端顯示更漂亮
util.inspect(object,[showHidden],[depth],[colors])
例

============= test.js =============
var util = require('util'); 
function Person() { 
    this.name = 'cx'; 
    this.toString = function() { 
    return this.name; 
    }; 
} 
var obj = new Person(); 
console.log(util.inspect(obj)); 
console.log(util.inspect(obj, true)); 

=============終端輸出=============
Person { name: 'cx', toString: [Function (anonymous)] }
Person {
  name: 'cx',
  toString: <ref *1> [Function (anonymous)] {
    [length]: 0,
    [name]: '',
    [arguments]: null,
    [caller]: null,
    [prototype]: { [constructor]: [Circular *1] }
  }
}

是否是數(shù)組

util.isArray(object)
例

var util = require('util');
// true
util.isArray([])
// true 
util.isArray(new Array)
// false 
util.isArray({})

是否是正則表達(dá)式

util.isRegExp(object)
例

var util = require('util');
// true
util.isRegExp(/some regexp/)
// true
util.isRegExp(new RegExp('another regexp'))
// false 
util.isRegExp({})

是否是日期

util.isDate(object)
例

var util = require('util');
// true
util.isDate(new Date())
// false (without 'new' returns a String)
util.isDate(Date())
// false  
util.isDate({})

Web 模塊

Node.js 提供了 http 模塊茅糜。http 模塊主要用于搭建 HTTP 服務(wù)端和客戶端,使用 HTTP 服務(wù)器或客戶端功能必須調(diào)用 http 模塊七芭。
var http = require('http');

  1. Web應(yīng)用架構(gòu)

Web服務(wù)器,目前最主流的3個(gè): Apache、Nginx蔑赘、IIS

Web應(yīng)用架構(gòu)
Web應(yīng)用架構(gòu)說(shuō)明
  1. Client 
    客戶端狸驳,一般指瀏覽器。瀏覽器可以通過(guò) HTTP 協(xié)議向服務(wù)器請(qǐng)求數(shù)據(jù)缩赛。
  2. Server 
    服務(wù)端耙箍,一般指 Web 服務(wù)器∷肘桑可以接收客戶端請(qǐng)求辩昆,并向客戶端發(fā)送響應(yīng)數(shù)據(jù)。
  3. Business 
    業(yè)務(wù)層旨袒, 通過(guò) Web 服務(wù)器處理應(yīng)用程序汁针,如與數(shù)據(jù)庫(kù)交互,邏輯運(yùn)算砚尽,調(diào)用外部程序等施无。
  4. Data 
    數(shù)據(jù)層,一般由數(shù)據(jù)庫(kù)組成必孤。

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<body>
    <h1>我的第一個(gè)標(biāo)題</h1>
    <p>我的第一個(gè)段落猾骡。</p>
</body>
</html>

server.js 服務(wù)器 (同一目錄下創(chuàng)建該文件)

var http = require('http');
var fs = require('fs');
var url = require('url');
 
 
// 創(chuàng)建服務(wù)器
http.createServer( function (request, response) {  
   // 解析請(qǐng)求,包括文件名
   var pathname = url.parse(request.url).pathname;
   
   // 輸出請(qǐng)求的文件名
   console.log("Request for " + pathname + " received.");
   
   // 從文件系統(tǒng)中讀取請(qǐng)求的文件內(nèi)容
   fs.readFile(pathname.substr(1), function (err, data) {
      if (err) {
         console.log(err);
         // HTTP 狀態(tài)碼: 404 : NOT FOUND
         // Content Type: text/html
         response.writeHead(404, {'Content-Type': 'text/html'});
      }else{             
         // HTTP 狀態(tài)碼: 200 : OK
         // Content Type: text/html
         response.writeHead(200, {'Content-Type': 'text/html'});    
         
         // 響應(yīng)文件內(nèi)容
         response.write(data.toString());        
      }
      //  發(fā)送響應(yīng)數(shù)據(jù)
      response.end();
   });   
}).listen(8088);
 
// 控制臺(tái)會(huì)輸出以下信息
console.log('Server running at http://127.0.0.1:8088/');

終端啟動(dòng)服務(wù)器:node server.js

瀏覽器輸入http://127.0.0.1:8088/index.html

終端輸出:Request for /index.html received.

client.js 客戶端

var http = require('http');
 
// 用于請(qǐng)求的選項(xiàng)
var options = {
   host: 'localhost',
   port: '8088',
   path: '/index.html'  
};
 
// 處理響應(yīng)的回調(diào)函數(shù)
var callback = function(response){
   // 不斷更新數(shù)據(jù)
   var body = '';
   response.on('data', function(data) {
      body += data;
   });
   
   response.on('end', function() {
      // 數(shù)據(jù)接收完成
      console.log(body);
   });
}
// 向服務(wù)端發(fā)送請(qǐng)求
var req = http.request(options, callback);
req.end();

執(zhí)行客戶端:node client.js(新開一個(gè)終端)

服務(wù)端-終端會(huì)輸出:
Request for /index.html received.

客戶端-終端會(huì)輸出html內(nèi)容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<body>
    <h1>我的第一個(gè)標(biāo)題</h1>
    <p>我的第一個(gè)段落。</p>
</body>
</html>

GET/POST請(qǐng)求

  1. 獲取GET請(qǐng)求內(nèi)容

server.js

var http = require('http');
var url = require('url');
var util = require('util');
 
http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    res.end(util.inspect(url.parse(req.url, true)));
}).listen(3000);

node server.js

瀏覽器輸入http://localhost:3000/user?name=cx&hello

server.js

var http = require('http');
var url = require('url');
var util = require('util');
 
http.createServer(function(req, res){
    res.writeHead(200, {'Content-Type': 'text/plain'});
 
    // 解析 url 參數(shù)
    var params = url.parse(req.url, true).query;
    res.write("name=" + params.name);
    res.write("\n");
    res.write("hello=" + params.hello);
    res.end();
 
}).listen(3000);

node server.js


瀏覽器輸入hhttp://localhost:3000/user?name=cx&hello=world
  1. 獲取POST請(qǐng)求內(nèi)容
 POST 請(qǐng)求的內(nèi)容全部的都在請(qǐng)求體中卓练,http.ServerRequest 并沒(méi)有一個(gè)屬性內(nèi)容為請(qǐng)求體隘蝎,原因是等待請(qǐng)求體傳輸可能是一件耗時(shí)的工作。

比如上傳文件襟企,而很多時(shí)候我們可能并不需要理會(huì)請(qǐng)求體的內(nèi)容嘱么,惡意的POST請(qǐng)求會(huì)大大消耗服務(wù)器的資源,所以 node.js 默認(rèn)是不會(huì)解析請(qǐng)求體的顽悼,當(dāng)你需要的時(shí)候曼振,需要手動(dòng)來(lái)做。

var http = require('http');
var querystring = require('querystring');
var util = require('util');
 
http.createServer(function(req, res){
    // 定義了一個(gè)post變量蔚龙,用于暫存請(qǐng)求體的信息
    var post = '';     
 
    // 通過(guò)req的data事件監(jiān)聽函數(shù)冰评,每當(dāng)接受到請(qǐng)求體的數(shù)據(jù),就累加到post變量中
    req.on('data', function(chunk){    
        post += chunk;
    });
 
    // 在end事件觸發(fā)后木羹,通過(guò)querystring.parse將post解析為真正的POST請(qǐng)求格式甲雅,然后向客戶端返回。
    req.on('end', function(){    
        post = querystring.parse(post);
        res.end(util.inspect(post));
    });
}).listen(3000);

例1(server.js)

var http = require('http');
var querystring = require('querystring');
 
var postHTML = 
  '<html><head><meta charset="utf-8"><title>Hello World</title></head>' +
  '<body>' +
  '<form method="post">' +
  '網(wǎng)站名: <input name="name"><br>' +
  '網(wǎng)站 URL: <input name="url"><br>' +
  '<input type="submit">' +
  '</form>' +
  '</body></html>';
 
http.createServer(function (req, res) {
  var body = "";
  req.on('data', function (chunk) {
    body += chunk;
  });
  req.on('end', function () {
    // 解析參數(shù)
    body = querystring.parse(body);
    // 設(shè)置響應(yīng)頭部信息及編碼
    res.writeHead(200, {'Content-Type': 'text/html; charset=utf8'});
 
    if(body.name && body.url) { // 輸出提交的數(shù)據(jù)
        res.write("網(wǎng)站名:" + body.name);
        res.write("<br>");
        res.write("網(wǎng)站 URL:" + body.url);
    } else {  // 輸出表單
        res.write(postHTML);
    }
    res.end();
  });
}).listen(3000);

node server.js


瀏覽器輸入http://localhost:3000
提交結(jié)果

多進(jìn)程

引入

const child_process = require('child_process');
Node.js 是以單線程的模式運(yùn)行的坑填,但它使用的是事件驅(qū)動(dòng)來(lái)處理并發(fā)抛人,這樣有助于在多核 cpu 的系統(tǒng)上創(chuàng)建多個(gè)子進(jìn)程,從而提高性能脐瑰。
每個(gè)子進(jìn)程總是帶有三個(gè)流對(duì)象:child.stdin,child.stdout 和child.stderr妖枚。他們可能會(huì)共享父進(jìn)程的 stdio 流,或者也可以是獨(dú)立的被導(dǎo)流的流對(duì)象苍在。
  1. child_process.exec(command[, options], callback)

使用子進(jìn)程執(zhí)行命令绝页,緩存子進(jìn)程的輸出,并將子進(jìn)程的輸出以回調(diào)函數(shù)參數(shù)的形式返回
等待進(jìn)程結(jié)束,一次性返回緩沖區(qū)的內(nèi)容

command
  將要執(zhí)行的命令
  是個(gè)字符串寂恬,參數(shù)使用空格隔開(例:'node support.js ')

options 
  參數(shù)
  是個(gè)對(duì)象
    1. cwd 
      子進(jìn)程的當(dāng)前工作目錄
      字符串
    2. env 
      環(huán)境變量鍵值對(duì)
      對(duì)象
    3. encoding
      字符編碼(默認(rèn): 'utf8')
      字符串
    4. shell
      將要執(zhí)行命令的 Shell(默認(rèn): 在 UNIX 中為/bin/sh续誉, 在 Windows 中為cmd.exe, Shell 應(yīng)當(dāng)能識(shí)別 -c開關(guān)在 UNIX 中掠剑,或 /s /c 在 Windows 中屈芜。 在Windows 中,命令行解析應(yīng)當(dāng)能兼容cmd.exe)
      字符串
    5. timeout
      超時(shí)時(shí)間(默認(rèn): 0)
      數(shù)字
    6. maxBuffer
      在 stdout 或 stderr 中允許存在的最大緩沖(二進(jìn)制)朴译,如果超出那么子進(jìn)程將會(huì)被殺死 (默認(rèn): 200*1024)
      數(shù)字
    7. killSignal 
      結(jié)束信號(hào)(默認(rèn):'SIGTERM')
      字符串
    8. uid
      設(shè)置用戶進(jìn)程的 ID
      數(shù)字
    9. gid
      設(shè)置進(jìn)程組的 ID
      數(shù)字

callback 
  回調(diào)函數(shù)
  包含三個(gè)參數(shù)error, stdout 和 stderr井佑。(例:function (error, stdout, stderr) {} )

例1

================ support.js  ================
console.log("進(jìn)程 " + process.argv[2] + " 執(zhí)行。" );

================ test.js ================
const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
    var workerProcess = child_process.exec('node support.js '+i, function (error, stdout, stderr) {
        if (error) {
            console.log(error.stack);
            console.log('Error code: '+error.code);
            console.log('Signal received: '+error.signal);
        }
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
    });
 
    workerProcess.on('exit', function (code) {
        console.log('子進(jìn)程已退出眠寿,退出碼 '+code);
    });
}

================ node test.js ================
子進(jìn)程已退出躬翁,退出碼 0
子進(jìn)程已退出,退出碼 0
子進(jìn)程已退出盯拱,退出碼 0
stdout: 進(jìn)程 2 執(zhí)行盒发。

stderr: 
stdout: 進(jìn)程 1 執(zhí)行例嘱。

stderr: 
stdout: 進(jìn)程 0 執(zhí)行。

stderr: 
  1. child_process.spawn(command[, args][, options])

使用指定的命令行參數(shù)創(chuàng)建新進(jìn)程
返回流 (stdout & stderr)宁舰,在進(jìn)程返回大量數(shù)據(jù)時(shí)使用拼卵。進(jìn)程一旦開始執(zhí)行時(shí) spawn() 就開始接收響應(yīng)。

command
  將要執(zhí)行的命令
  是個(gè)字符串
args
  字符串參數(shù)數(shù)組
  是個(gè)Array 

options 
    是個(gè)Object
    1. cwd 
      子進(jìn)程的當(dāng)前工作目錄
      String 
    2. env  
      環(huán)境變量鍵值對(duì)
      Object
    3. stdio  
      子進(jìn)程的 stdio 配置
      Array|String
    4. detached  
      這個(gè)子進(jìn)程將會(huì)變成進(jìn)程組的領(lǐng)導(dǎo)
      Boolean
    5. uid 
      設(shè)置用戶進(jìn)程的 ID
      Number
    6. gid  
      設(shè)置進(jìn)程組的 ID
      Number

例1

================ support.js  ================
console.log("進(jìn)程 " + process.argv[2] + " 執(zhí)行蛮艰。" );

================ test.js ================
const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
   var workerProcess = child_process.spawn('node', ['support.js', i]);
 
   workerProcess.stdout.on('data', function (data) {
      console.log('stdout: ' + data);
   });
   workerProcess.stderr.on('data', function (data) {
      console.log('stderr: ' + data);
   });
   workerProcess.on('close', function (code) {
      console.log('子進(jìn)程已退出腋腮,退出碼 '+code);
   });
}

================ node test.js ================
stdout: 進(jìn)程 0 執(zhí)行。

stdout: 進(jìn)程 1 執(zhí)行壤蚜。

stdout: 進(jìn)程 2 執(zhí)行即寡。

子進(jìn)程已退出,退出碼 0
子進(jìn)程已退出袜刷,退出碼 0
子進(jìn)程已退出聪富,退出碼 0
  1. child_process.fork(modulePath[, args][, options])

spawn() 方法的特殊形式,用于創(chuàng)建進(jìn)程著蟹。
如 fork('./son.js') 相當(dāng)于 spawn('node', ['./son.js']) 墩蔓。
與spawn方法不同的是,fork會(huì)在父進(jìn)程與子進(jìn)程之間萧豆,建立一個(gè)通信管道钢拧,用于進(jìn)程之間的通信

modulePath
  將要在子進(jìn)程中運(yùn)行的模塊
  String

args
  字符串參數(shù)數(shù)組
  Array

options
  Object
    1. cwd  
      子進(jìn)程的當(dāng)前工作目錄
      String
    2. env  
      環(huán)境變量鍵值對(duì)
      Object
    3. execPath  
      創(chuàng)建子進(jìn)程的可執(zhí)行文件
      String
    4. execArgv  
      子進(jìn)程的可執(zhí)行文件的字符串參數(shù)數(shù)組(默認(rèn): process.execArgv)
      Array
    5. silent  
      如果為true,子進(jìn)程的stdin炕横,stdout和stderr將會(huì)被關(guān)聯(lián)至父進(jìn)程,
      如果為false葡粒,它們將會(huì)從父進(jìn)程中繼承份殿。(默認(rèn)為:false)
      Boolean
    6. uid  
      設(shè)置用戶進(jìn)程的 ID
      Number
    7. gid  
      設(shè)置進(jìn)程組的 ID
      Number
================ support.js  ================
console.log("進(jìn)程 " + process.argv[2] + " 執(zhí)行。" );

================ test.js ================
const fs = require('fs');
const child_process = require('child_process');
 
for(var i=0; i<3; i++) {
   var worker_process = child_process.fork("support.js", [i]);    

   worker_process.on('close', function (code) {
      console.log('子進(jìn)程已退出嗽交,退出碼 ' + code);
   });
}

================ node test.js ================
進(jìn)程 0 執(zhí)行卿嘲。
進(jìn)程 1 執(zhí)行。
進(jìn)程 2 執(zhí)行夫壁。
子進(jìn)程已退出拾枣,退出碼 0
子進(jìn)程已退出,退出碼 0
子進(jìn)程已退出盒让,退出碼 0

JXcore(打包)

JXcore:一個(gè)支持多線程的Node.js發(fā)行版本

  1. 安裝JXcore

JXcore安裝包github地址

1. 下載JXcore安裝包
2. 解壓后找到對(duì)應(yīng)平臺(tái)的zip包梅肤,解壓后將jx可執(zhí)行文件復(fù)制到/usr/local/bin目錄下
3. export PATH=$PATH:/usr/local/bin
4. 查看是否安裝成功(出現(xiàn)jx版本號(hào),則成功) 
  jx --version
  1. 將項(xiàng)目打包成一個(gè)可運(yùn)行的.jx文件
打包(指定 index.js 為 Node.js 項(xiàng)目的主文件)
  jx package index.js index

會(huì)生成2文件
  1. index.jxp邑茄。中間件文件姨蝴,包含了需要編譯的完整項(xiàng)目信息。
  2. index.jx肺缕。完整包信息的二進(jìn)制文件左医,可運(yùn)行在客戶端上授帕。

運(yùn)行
  jx index.jx

Buffer(緩沖區(qū))

JavaScript只有字符串?dāng)?shù)據(jù)類型,沒(méi)有二進(jìn)制數(shù)據(jù)類型浮梢。
但在處理像TCP流或文件流時(shí)跛十,必須使用到二進(jìn)制數(shù)據(jù)。因此在 Node.js中秕硝,定義了一個(gè) Buffer 類芥映,該類用來(lái)創(chuàng)建一個(gè)專門存放二進(jìn)制數(shù)據(jù)的緩存區(qū)。

在 Node.js 中缝裤,Buffer 類是隨 Node 內(nèi)核一起發(fā)布的核心庫(kù)屏轰。
Buffer 庫(kù)為 Node.js 帶來(lái)了一種存儲(chǔ)原始數(shù)據(jù)的方法,可以讓 Node.js 處理二進(jìn)制數(shù)據(jù)憋飞,每當(dāng)需要在 Node.js 中處理I/O操作中移動(dòng)的數(shù)據(jù)時(shí)霎苗,就有可能使用 Buffer 庫(kù)。
原始數(shù)據(jù)存儲(chǔ)在 Buffer 類的實(shí)例中榛做。
一個(gè) Buffer 類似于一個(gè)整數(shù)數(shù)組唁盏,但它對(duì)應(yīng)于 V8 堆內(nèi)存之外的一塊原始內(nèi)存。

在v6.0之前創(chuàng)建Buffer對(duì)象直接使用new Buffer()構(gòu)造函數(shù)來(lái)創(chuàng)建對(duì)象實(shí)例检眯,但是Buffer對(duì)內(nèi)存的權(quán)限操作相比很大厘擂,可以直接捕獲一些敏感信息,所以在v6.0以后锰瘸,官方文檔里面建議使用 Buffer.from() 接口去創(chuàng)建Buffer對(duì)象刽严。
  1. Buffer 與字符編碼

Buffer實(shí)例一般用于表示編碼字符的序列,比如 UTF-8 避凝、 UCS2 舞萄、 Base64 、或十六進(jìn)制編碼的數(shù)據(jù)管削。
通過(guò)使用顯式的字符編碼倒脓,就可以在 Buffer 實(shí)例與普通的 JavaScript 字符串之間進(jìn)行相互轉(zhuǎn)換。

Node.js 目前支持的字符編碼包括:
  1. ascii 
    僅支持 7 位 ASCII 數(shù)據(jù)含思。如果設(shè)置去掉高位的話崎弃,這種編碼是非常快的含潘。
  2. utf8 
    多字節(jié)編碼的 Unicode 字符饲做。許多網(wǎng)頁(yè)和其他文檔格式都使用 UTF-8 。
  3. utf16le 
    2 或 4 個(gè)字節(jié)调鬓,小字節(jié)序編碼的 Unicode 字符艇炎。支持代理對(duì)(U+10000 至 U+10FFFF)。
  4. ucs2 
    utf16le 的別名腾窝。
  5. base64 
    Base64 編碼缀踪。
  6. latin1  
    一種把 Buffer 編碼成一字節(jié)編碼的字符串的方式居砖。
  7. binary 
    latin1 的別名。
  8. hex 
    將每個(gè)字節(jié)編碼為兩個(gè)十六進(jìn)制字符

例1

const buf = Buffer.from('cx', 'ascii');

// 輸出 6378
console.log(buf.toString('hex'));

// 輸出 Y3g=
console.log(buf.toString('base64'));
  1. 創(chuàng)建 Buffer 類
Buffer.alloc(size[, fill[, encoding]])
    返回一個(gè)指定大小的 Buffer 實(shí)例驴娃,如果沒(méi)有設(shè)置 fill奏候,則默認(rèn)填滿 0
Buffer.allocUnsafe(size)
    返回一個(gè)指定大小的 Buffer 實(shí)例,但是它不會(huì)被初始化唇敞,所以它可能包含敏感的數(shù)據(jù)
Buffer.allocUnsafeSlow(size)
Buffer.from(array)
    返回一個(gè)被 array 的值初始化的新的 Buffer 實(shí)例(傳入的 array 的元素只能是數(shù)字蔗草,不然就會(huì)自動(dòng)被 0 覆蓋)
Buffer.from(arrayBuffer[, byteOffset[, length]])
    返回一個(gè)新建的與給定的 ArrayBuffer 共享同一內(nèi)存的 Buffer。
Buffer.from(buffer)
    復(fù)制傳入的 Buffer 實(shí)例的數(shù)據(jù)疆柔,并返回一個(gè)新的 Buffer 實(shí)例
Buffer.from(string[, encoding])
    返回一個(gè)被 string 的值初始化的新的 Buffer 實(shí)例

例1

// 創(chuàng)建一個(gè)長(zhǎng)度為 10咒精、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 創(chuàng)建一個(gè)長(zhǎng)度為 10旷档、且用 0x1 填充的 Buffer模叙。 
const buf2 = Buffer.alloc(10, 1);

// 創(chuàng)建一個(gè)長(zhǎng)度為 10尚蝌、且未初始化的 Buffer缝龄。
// 這個(gè)方法比調(diào)用 Buffer.alloc() 更快,
// 但返回的 Buffer 實(shí)例可能包含舊數(shù)據(jù)燥撞,
// 因此需要使用 fill() 或 write() 重寫厂庇。
const buf3 = Buffer.allocUnsafe(10);

// 創(chuàng)建一個(gè)包含 [0x1, 0x2, 0x3] 的 Buffer渠啊。
const buf4 = Buffer.from([1, 2, 3]);

// 創(chuàng)建一個(gè)包含 UTF-8 字節(jié) [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 創(chuàng)建一個(gè)包含 Latin-1 字節(jié) [0x74, 0xe9, 0x73, 0x74] 的 Buffer权旷。
const buf6 = Buffer.from('tést', 'latin1');
  1. 寫入緩沖區(qū)
buf.write(string[, offset[, length]][, encoding])

根據(jù) encoding 的字符編碼寫入 string 到 buf 中的 offset 位置替蛉。 
length 參數(shù)是寫入的字節(jié)數(shù)。 如果 buf 沒(méi)有足夠的空間保存整個(gè)字符串拄氯,則只會(huì)寫入 string 的一部分灭返。 只部分解碼的字符不會(huì)被寫入。
返回實(shí)際寫入的大小坤邪。如果 buffer 空間不足, 則只會(huì)寫入部分字符串罚缕。
參數(shù)說(shuō)明

  1. string 
    寫入緩沖區(qū)的字符串艇纺。
  2. offset 
    緩沖區(qū)開始寫入的索引值,默認(rèn)為 0 邮弹。
  3. length 
    寫入的字節(jié)數(shù)黔衡,默認(rèn)為 buffer.length
  4. encoding 
    使用的編碼。默認(rèn)為 'utf8' 腌乡。

例1

buf = Buffer.alloc(256);
len = buf.write("www.baidu.com");

console.log("寫入字節(jié)數(shù) : "+  len);

================
寫入字節(jié)數(shù) : 13
  1. 從緩沖區(qū)讀取數(shù)據(jù)
buf.toString([encoding[, start[, end]]])

解碼緩沖區(qū)數(shù)據(jù)并使用指定的編碼返回字符串盟劫。
參數(shù)說(shuō)明

  1. encoding 
    使用的編碼。默認(rèn)為 'utf8' 与纽。
  2. start 
    指定開始讀取的索引位置侣签,默認(rèn)為 0塘装。
  3. end 
    結(jié)束位置,默認(rèn)為緩沖區(qū)的末尾影所。

例1

buf = Buffer.alloc(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97;
}

console.log( buf.toString('ascii'));       // 輸出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5));   //使用 'ascii' 編碼, 并輸出: abcde
console.log( buf.toString('utf8',0,5));    // 使用 'utf8' 編碼, 并輸出: abcde
console.log( buf.toString(undefined,0,5)); // 使用默認(rèn)的 'utf8' 編碼, 并輸出: abcde

================
abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde
  1. 將 Buffer 轉(zhuǎn)換為 JSON 對(duì)象
buf.toJSON()

當(dāng)字符串化一個(gè) Buffer 實(shí)例時(shí)蹦肴,JSON.stringify() 會(huì)隱式地調(diào)用該 toJSON()。

例1

const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]);
const json = JSON.stringify(buf);

// 輸出: {"type":"Buffer","data":[1,2,3,4,5]}
console.log(json);

const copy = JSON.parse(json, (key, value) => {
  return value && value.type === 'Buffer' ?
    Buffer.from(value.data) :
    value;
});

// 輸出: <Buffer 01 02 03 04 05>
console.log(copy);
==================

{"type":"Buffer","data":[1,2,3,4,5]}
<Buffer 01 02 03 04 05>
  1. 緩沖區(qū)合并
Buffer.concat(list[, totalLength])

返回一個(gè)多個(gè)成員合并的新 Buffer 對(duì)象
參數(shù)說(shuō)明

  1. list 
    用于合并的 Buffer 對(duì)象數(shù)組列表猴娩。
  2. totalLength 
    指定合并后Buffer對(duì)象的總長(zhǎng)度阴幌。

例1

var buffer1 = Buffer.from(('hello'));
var buffer2 = Buffer.from(('world'));
var buffer3 = Buffer.concat([buffer1,buffer2]);
console.log("buffer3 內(nèi)容: " + buffer3.toString());
=====================
buffer3 內(nèi)容: helloworld
  1. 緩沖區(qū)比較
buf.compare(otherBuffer);
返回一個(gè)數(shù)字,表示 buf 在 otherBuffer 之前卷中,之后或相同矛双。
參數(shù)說(shuō)明

  1. otherBuffer 
    與 buf 對(duì)象比較的另外一個(gè) Buffer 對(duì)象。 

例1

var buffer1 = Buffer.from('ABC');
var buffer2 = Buffer.from('ABCD');
var result = buffer1.compare(buffer2);

if(result < 0) {
   console.log(buffer1 + " 在 " + buffer2 + "之前");
}else if(result == 0){
   console.log(buffer1 + " 與 " + buffer2 + "相同");
}else {
   console.log(buffer1 + " 在 " + buffer2 + "之后");
}
======================
ABC 在 ABCD之前
  1. 拷貝緩沖區(qū)
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])
參數(shù)說(shuō)明

  1. targetBuffer 
    要拷貝的 Buffer 對(duì)象蟆豫。
  2. targetStart 
    數(shù)字, 可選, 默認(rèn): 0
  3. sourceStart 
    數(shù)字, 可選, 默認(rèn): 0
  4. sourceEnd 
    數(shù)字, 可選, 默認(rèn): buffer.length

例1

var buf1 = Buffer.from('abcdefghijkl');
var buf2 = Buffer.from('RUNOOB');

//將 buf2 插入到 buf1 指定位置上
buf2.copy(buf1, 2);

console.log(buf1.toString());

===================
abRUNOOBijkl
  1. 緩沖區(qū)裁剪
buf.slice([start[, end]])

返回一個(gè)新的緩沖區(qū)议忽,它和舊緩沖區(qū)指向同一塊內(nèi)存,但是從索引 start 到 end 的位置剪切无埃。
參數(shù)說(shuō)明

  1. start 
    數(shù)字, 可選, 默認(rèn): 0
  2. end 
    數(shù)字, 可選, 默認(rèn): buffer.length

例1

var buffer1 = Buffer.from('runoob');
// 剪切緩沖區(qū)
var buffer2 = buffer1.slice(0,2);
console.log("buffer2 content: " + buffer2.toString());
==================
buffer2 content: ru
  1. 緩沖區(qū)長(zhǎng)度
buf.length;

返回 Buffer 對(duì)象所占據(jù)的內(nèi)存長(zhǎng)度

例1

var buffer = Buffer.from('hello world');
//  緩沖區(qū)長(zhǎng)度
console.log("buffer length: " + buffer.length);
==================
buffer length: 11
方法 說(shuō)明
new Buffer(size) 分配一個(gè)新的 size 大小單位為8位字節(jié)的 buffer徙瓶。 注意, size 必須小于 kMaxLength,否則嫉称,將會(huì)拋出異常 RangeError侦镇。廢棄的: 使用 Buffer.alloc() 代替(或 Buffer.allocUnsafe())。
new Buffer(buffer) 拷貝參數(shù) buffer 的數(shù)據(jù)到 Buffer 實(shí)例织阅。廢棄的: 使用 Buffer.from(buffer) 代替壳繁。
new Buffer(str[, encoding]) 分配一個(gè)新的 buffer ,其中包含著傳入的 str 字符串荔棉。 encoding 編碼方式默認(rèn)為 'utf8'闹炉。 廢棄的: 使用 Buffer.from(string[, encoding]) 代替。
buf.length 返回這個(gè) buffer 的 bytes 數(shù)润樱。注意這未必是 buffer 里面內(nèi)容的大小渣触。length 是 buffer 對(duì)象所分配的內(nèi)存數(shù),它不會(huì)隨著這個(gè) buffer 對(duì)象內(nèi)容的改變而改變壹若。
buf.write(string[, offset[, length]][, encoding]) 根據(jù)參數(shù) offset 偏移量和指定的 encoding 編碼方式嗅钻,將參數(shù) string 數(shù)據(jù)寫入buffer。 offset 偏移量默認(rèn)值是 0, encoding 編碼方式默認(rèn)是 utf8店展。 length 長(zhǎng)度是將要寫入的字符串的 bytes 大小养篓。 返回 number 類型,表示寫入了多少 8 位字節(jié)流赂蕴。如果 buffer 沒(méi)有足夠的空間來(lái)放整個(gè) string柳弄,它將只會(huì)只寫入部分字符串。 length 默認(rèn)是 buffer.length - offset概说。 這個(gè)方法不會(huì)出現(xiàn)寫入部分字符碧注。
buf.writeUIntLE(value, offset, byteLength[, noAssert]) 將 value 寫入到 buffer 里嚣伐, 它由 offset 和 byteLength 決定,最高支持 48 位無(wú)符號(hào)整數(shù)应闯,小端對(duì)齊纤控。noAssert 值為 true 時(shí),不再驗(yàn)證 value 和 offset 的有效性碉纺。 默認(rèn)是 false船万。
buf.writeUIntBE(value, offset, byteLength[, noAssert]) 將 value 寫入到 buffer 里, 它由 offset 和 byteLength 決定骨田,最高支持 48 位無(wú)符號(hào)整數(shù)耿导,大端對(duì)齊。noAssert 值為 true 時(shí)态贤,不再驗(yàn)證 value 和 offset 的有效性舱呻。 默認(rèn)是 false。
buf.writeIntLE(value, offset, byteLength[, noAssert]) 將value 寫入到 buffer 里悠汽, 它由offset 和 byteLength 決定箱吕,最高支持48位有符號(hào)整數(shù),小端對(duì)齊柿冲。noAssert 值為 true 時(shí)茬高,不再驗(yàn)證 value 和 offset 的有效性。 默認(rèn)是 false假抄。
buf.writeIntBE(value, offset, byteLength[, noAssert]) 將value 寫入到 buffer 里怎栽, 它由offset 和 byteLength 決定,最高支持48位有符號(hào)整數(shù)宿饱,大端對(duì)齊熏瞄。noAssert 值為 true 時(shí),不再驗(yàn)證 value 和 offset 的有效性谬以。 默認(rèn)是 false强饮。
buf.readUIntLE(offset, byteLength[, noAssert]) 支持讀取 48 位以下的無(wú)符號(hào)數(shù)字,小端對(duì)齊为黎。noAssert 值為 true 時(shí)胡陪, offset 不再驗(yàn)證是否超過(guò) buffer 的長(zhǎng)度,默認(rèn)為 false碍舍。
buf.readUIntBE(offset, byteLength[, noAssert]) 支持讀取 48 位以下的無(wú)符號(hào)數(shù)字,大端對(duì)齊邑雅。noAssert 值為 true 時(shí)片橡, offset 不再驗(yàn)證是否超過(guò) buffer 的長(zhǎng)度,默認(rèn)為 false淮野。
buf.readIntLE(offset, byteLength[, noAssert]) 支持讀取 48 位以下的有符號(hào)數(shù)字捧书,小端對(duì)齊吹泡。noAssert 值為 true 時(shí), offset 不再驗(yàn)證是否超過(guò) buffer 的長(zhǎng)度经瓷,默認(rèn)為 false爆哑。
buf.readIntBE(offset, byteLength[, noAssert]) 支持讀取 48 位以下的有符號(hào)數(shù)字,大端對(duì)齊舆吮。noAssert 值為 true 時(shí)揭朝, offset 不再驗(yàn)證是否超過(guò) buffer 的長(zhǎng)度,默認(rèn)為 false色冀。
buf.toString([encoding[, start[, end]]]) 根據(jù) encoding 參數(shù)(默認(rèn)是 'utf8')返回一個(gè)解碼過(guò)的 string 類型潭袱。還會(huì)根據(jù)傳入的參數(shù) start (默認(rèn)是 0) 和 end (默認(rèn)是 buffer.length)作為取值范圍。
buf.toJSON() 將 Buffer 實(shí)例轉(zhuǎn)換為 JSON 對(duì)象锋恬。
buf[index] 獲取或設(shè)置指定的字節(jié)屯换。返回值代表一個(gè)字節(jié),所以返回值的合法范圍是十六進(jìn)制0x00到0xFF 或者十進(jìn)制0至 255与学。
buf.equals(otherBuffer) 比較兩個(gè)緩沖區(qū)是否相等彤悔,如果是返回 true,否則返回 false索守。
buf.compare(otherBuffer) 比較兩個(gè) Buffer 對(duì)象晕窑,返回一個(gè)數(shù)字,表示 buf 在 otherBuffer 之前蕾盯,之后或相同幕屹。
buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]]) buffer 拷貝,源和目標(biāo)可以相同级遭。 targetStart 目標(biāo)開始偏移和 sourceStart 源開始偏移默認(rèn)都是 0望拖。 sourceEnd 源結(jié)束位置偏移默認(rèn)是源的長(zhǎng)度 buffer.length 。
buf.slice([start[, end]]) 剪切 Buffer 對(duì)象挫鸽,根據(jù) start(默認(rèn)是 0 ) 和 end (默認(rèn)是 buffer.length ) 偏移和裁剪了索引说敏。 負(fù)的索引是從 buffer 尾部開始計(jì)算的。
buf.readUInt8(offset[, noAssert]) 根據(jù)指定的偏移量丢郊,讀取一個(gè)無(wú)符號(hào) 8 位整數(shù)盔沫。若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 如果這樣 offset 可能會(huì)超出buffer 的末尾枫匾。默認(rèn)是 false架诞。
buf.readUInt16LE(offset[, noAssert]) 根據(jù)指定的偏移量,使用特殊的 endian 字節(jié)序格式讀取一個(gè)無(wú)符號(hào) 16 位整數(shù)干茉。若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)谴忧。 這意味著 offset 可能會(huì)超出 buffer 的末尾。默認(rèn)是 false。
buf.readUInt16BE(offset[, noAssert]) 根據(jù)指定的偏移量沾谓,使用特殊的 endian 字節(jié)序格式讀取一個(gè)無(wú)符號(hào) 16 位整數(shù)委造,大端對(duì)齊。若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)均驶。 這意味著 offset 可能會(huì)超出 buffer 的末尾昏兆。默認(rèn)是 false。
buf.readUInt32LE(offset[, noAssert]) 根據(jù)指定的偏移量妇穴,使用指定的 endian 字節(jié)序格式讀取一個(gè)無(wú)符號(hào) 32 位整數(shù)爬虱,小端對(duì)齊。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)伟骨。 這意味著 offset 可能會(huì)超出buffer 的末尾饮潦。默認(rèn)是 false。
buf.readUInt32BE(offset[, noAssert]) 根據(jù)指定的偏移量携狭,使用指定的 endian 字節(jié)序格式讀取一個(gè)無(wú)符號(hào) 32 位整數(shù)继蜡,大端對(duì)齊。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)逛腿。 這意味著 offset 可能會(huì)超出buffer 的末尾稀并。默認(rèn)是 false。
buf.readInt8(offset[, noAssert]) 根據(jù)指定的偏移量单默,讀取一個(gè)有符號(hào) 8 位整數(shù)碘举。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出 buffer 的末尾搁廓。默認(rèn)是 false引颈。
buf.readInt16LE(offset[, noAssert]) 根據(jù)指定的偏移量,使用特殊的 endian 格式讀取一個(gè) 有符號(hào) 16 位整數(shù)境蜕,小端對(duì)齊蝙场。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出 buffer 的末尾粱年。默認(rèn)是 false售滤。
buf.readInt16BE(offset[, noAssert]) 根據(jù)指定的偏移量,使用特殊的 endian 格式讀取一個(gè) 有符號(hào) 16 位整數(shù)台诗,大端對(duì)齊完箩。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出 buffer 的末尾拉队。默認(rèn)是 false弊知。
buf.readInt32LE(offset[, noAssert]) 根據(jù)指定的偏移量,使用指定的 endian 字節(jié)序格式讀取一個(gè)有符號(hào) 32 位整數(shù)粱快,小端對(duì)齊秩彤。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)夺鲜。 這意味著 offset 可能會(huì)超出buffer 的末尾。默認(rèn)是 false呐舔。
buf.readInt32BE(offset[, noAssert]) 根據(jù)指定的偏移量,使用指定的 endian 字節(jié)序格式讀取一個(gè)有符號(hào) 32 位整數(shù)慷蠕,大端對(duì)齊珊拼。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出buffer 的末尾流炕。默認(rèn)是 false澎现。
buf.readFloatLE(offset[, noAssert]) 根據(jù)指定的偏移量,使用指定的 endian 字節(jié)序格式讀取一個(gè) 32 位雙浮點(diǎn)數(shù)每辟,小端對(duì)齊剑辫。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出buffer的末尾渠欺。默認(rèn)是 false妹蔽。
buf.readFloatBE(offset[, noAssert]) 根據(jù)指定的偏移量,使用指定的 endian 字節(jié)序格式讀取一個(gè) 32 位雙浮點(diǎn)數(shù)挠将,大端對(duì)齊胳岂。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出buffer的末尾舔稀。默認(rèn)是 false乳丰。
buf.readDoubleLE(offset[, noAssert]) 根據(jù)指定的偏移量,使用指定的 endian字節(jié)序格式讀取一個(gè) 64 位雙精度數(shù)内贮,小端對(duì)齊产园。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出buffer 的末尾夜郁。默認(rèn)是 false什燕。
buf.readDoubleBE(offset[, noAssert]) 根據(jù)指定的偏移量,使用指定的 endian字節(jié)序格式讀取一個(gè) 64 位雙精度數(shù)拂酣,大端對(duì)齊秋冰。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)。 這意味著 offset 可能會(huì)超出buffer 的末尾婶熬。默認(rèn)是 false剑勾。
buf.writeUInt8(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量將 value 寫入 buffer。注意:value 必須是一個(gè)合法的無(wú)符號(hào) 8 位整數(shù)赵颅。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 offset 偏移量參數(shù)虽另。 這意味著 value 可能過(guò)大,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄饺谬。 除非你對(duì)這個(gè)參數(shù)非常有把握捂刺,否則不要使用谣拣。默認(rèn)是 false。
buf.writeUInt16LE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer族展。注意:value 必須是一個(gè)合法的無(wú)符號(hào) 16 位整數(shù)森缠,小端對(duì)齊。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)仪缸。 這意味著 value 可能過(guò)大贵涵,或者 offset 可能會(huì)超出buffer的末尾從而造成 value 被丟棄。 除非你對(duì)這個(gè)參數(shù)非常有把握恰画,否則盡量不要使用宾茂。默認(rèn)是 false。
buf.writeUInt16BE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer拴还。注意:value 必須是一個(gè)合法的無(wú)符號(hào) 16 位整數(shù)跨晴,大端對(duì)齊。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)片林。 這意味著 value 可能過(guò)大端盆,或者 offset 可能會(huì)超出buffer的末尾從而造成 value 被丟棄。 除非你對(duì)這個(gè)參數(shù)非常有把握拇厢,否則盡量不要使用爱谁。默認(rèn)是 false。
buf.writeUInt32LE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式(LITTLE-ENDIAN:小字節(jié)序)將 value 寫入buffer孝偎。注意:value 必須是一個(gè)合法的無(wú)符號(hào) 32 位整數(shù)访敌,小端對(duì)齊。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)衣盾。 這意味著value 可能過(guò)大寺旺,或者offset可能會(huì)超出buffer的末尾從而造成 value 被丟棄。 除非你對(duì)這個(gè)參數(shù)非常有把握势决,否則盡量不要使用阻塑。默認(rèn)是 false。
buf.writeUInt32BE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式(Big-Endian:大字節(jié)序)將 value 寫入buffer果复。注意:value 必須是一個(gè)合法的有符號(hào) 32 位整數(shù)陈莽。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)。 這意味著 value 可能過(guò)大虽抄,或者offset可能會(huì)超出buffer的末尾從而造成 value 被丟棄走搁。 除非你對(duì)這個(gè)參數(shù)非常有把握,否則盡量不要使用迈窟。默認(rèn)是 false私植。
buf.writeInt8(value, offset[, noAssert])
buf.writeInt16LE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer。注意:value 必須是一個(gè)合法的 signed 16 位整數(shù)车酣。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)曲稼。 這意味著 value 可能過(guò)大索绪,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄。 除非你對(duì)這個(gè)參數(shù)非常有把握贫悄,否則盡量不要使用瑞驱。默認(rèn)是 false 。
buf.writeInt16BE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer窄坦。注意:value 必須是一個(gè)合法的 signed 16 位整數(shù)钱烟。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)。 這意味著 value 可能過(guò)大嫡丙,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄。 除非你對(duì)這個(gè)參數(shù)非常有把握读第,否則盡量不要使用曙博。默認(rèn)是 false 。
buf.writeInt32LE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer怜瞒。注意:value 必須是一個(gè)合法的 signed 32 位整數(shù)父泳。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)。 這意味著 value 可能過(guò)大吴汪,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄惠窄。 除非你對(duì)這個(gè)參數(shù)非常有把握,否則盡量不要使用漾橙。默認(rèn)是 false杆融。
buf.writeInt32BE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer。注意:value 必須是一個(gè)合法的 signed 32 位整數(shù)霜运。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)脾歇。 這意味著 value 可能過(guò)大,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄淘捡。 除非你對(duì)這個(gè)參數(shù)非常有把握藕各,否則盡量不要使用。默認(rèn)是 false焦除。
buf.writeFloatLE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer 激况。注意:當(dāng) value 不是一個(gè) 32 位浮點(diǎn)數(shù)類型的值時(shí),結(jié)果將是不確定的膘魄。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)乌逐。 這意味著 value可能過(guò)大,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄瓣距。 除非你對(duì)這個(gè)參數(shù)非常有把握黔帕,否則盡量不要使用。默認(rèn)是 false蹈丸。
buf.writeFloatBE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer 成黄。注意:當(dāng) value 不是一個(gè) 32 位浮點(diǎn)數(shù)類型的值時(shí)呐芥,結(jié)果將是不確定的。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)奋岁。 這意味著 value可能過(guò)大思瘟,或者 offset 可能會(huì)超出 buffer 的末尾從而造成 value 被丟棄。 除非你對(duì)這個(gè)參數(shù)非常有把握闻伶,否則盡量不要使用滨攻。默認(rèn)是 false。
buf.writeDoubleLE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer蓝翰。注意:value 必須是一個(gè)有效的 64 位double 類型的值光绕。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)。 這意味著 value 可能過(guò)大畜份,或者 offset 可能會(huì)超出 buffer 的末尾從而造成value被丟棄诞帐。 除非你對(duì)這個(gè)參數(shù)非常有把握,否則盡量不要使用爆雹。默認(rèn)是 false停蕉。
buf.writeDoubleBE(value, offset[, noAssert]) 根據(jù)傳入的 offset 偏移量和指定的 endian 格式將 value 寫入 buffer。注意:value 必須是一個(gè)有效的 64 位double 類型的值钙态。 若參數(shù) noAssert 為 true 將不會(huì)驗(yàn)證 value 和 offset 偏移量參數(shù)慧起。 這意味著 value 可能過(guò)大,或者 offset 可能會(huì)超出 buffer 的末尾從而造成value被丟棄册倒。 除非你對(duì)這個(gè)參數(shù)非常有把握蚓挤,否則盡量不要使用。默認(rèn)是 false驻子。
buf.fill(value[, offset][, end]) 使用指定的 value 來(lái)填充這個(gè) buffer屈尼。如果沒(méi)有指定 offset (默認(rèn)是 0) 并且 end (默認(rèn)是 buffer.length) ,將會(huì)填充整個(gè)buffer拴孤。
const buf = Buffer.allocUnsafe(6);
buf.writeUIntLE(0x1234567890ab, 0, 6);
// 輸出: <Buffer ab 90 78 56 34 12>
console.log(buf);
const buf = Buffer.allocUnsafe(6);
buf.writeUIntBE(0x1234567890ab, 0, 6);
// 輸出: <Buffer 12 34 56 78 90 ab>
console.log(buf);

待續(xù)脾歧。。演熟。鞭执。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芒粹,一起剝皮案震驚了整個(gè)濱河市兄纺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌化漆,老刑警劉巖估脆,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異座云,居然都是意外死亡疙赠,警方通過(guò)查閱死者的電腦和手機(jī)付材,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)圃阳,“玉大人厌衔,你說(shuō)我怎么就攤上這事『丛溃” “怎么了富寿?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)锣夹。 經(jīng)常有香客問(wèn)我拉一,道長(zhǎng)琢蛤,這世上最難降的妖魔是什么嗤军? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任等舔,我火速辦了婚禮口四,結(jié)果婚禮上拜效,老公的妹妹穿的比我還像新娘创南。我一直安慰自己巷屿,他們只是感情好赃梧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布滤蝠。 她就那樣靜靜地躺著,像睡著了一般授嘀。 火紅的嫁衣襯著肌膚如雪物咳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天蹄皱,我揣著相機(jī)與錄音览闰,去河邊找鬼。 笑死巷折,一個(gè)胖子當(dāng)著我的面吹牛压鉴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播锻拘,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼油吭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了署拟?” 一聲冷哼從身側(cè)響起婉宰,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎推穷,沒(méi)想到半個(gè)月后心包,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馒铃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蟹腾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痕惋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岭佳,死狀恐怖血巍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情珊随,我是刑警寧澤述寡,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站叶洞,受9級(jí)特大地震影響鲫凶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衩辟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一螟炫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧艺晴,春花似錦昼钻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至狈究,卻和暖如春碗淌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抖锥。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工亿眠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人磅废。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓纳像,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拯勉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爹耗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350