真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Buffer怎么在Node.js中使用

這篇文章將為大家詳細講解有關(guān)Buffer怎么在Node.js中使用,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

成都創(chuàng)新互聯(lián)公司專業(yè)為企業(yè)提供太湖網(wǎng)站建設(shè)、太湖做網(wǎng)站、太湖網(wǎng)站設(shè)計、太湖網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、太湖企業(yè)網(wǎng)站模板建站服務(wù),10余年太湖做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。

Buffer:

fs.readFile('filename', function (err, buf) {
 // 
});

在使用net或http模塊來接收網(wǎng)絡(luò)數(shù)據(jù)時,data事件的參數(shù)也是一個 Buffer,這時我們還需要使用Buffer.concat()來做數(shù)據(jù)拼接:

var bufs = [];
conn.on('data', function (buf) {
 bufs.push(buf);
});
conn.on('end', function () {
 // 接收數(shù)據(jù)結(jié)束后,拼接所有收到的 Buffer 對象
 var buf = Buffer.concat(bufs);
});

還可以利用Buffer.toString()來做轉(zhuǎn)換base64或十六進制字符的轉(zhuǎn)換,比如:

console.log(new Buffer('hello, world!').toString('base64'));
// 轉(zhuǎn)換成 base64 字符串:aGVsbG8sIHdvcmxkIQ==

console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString());
// 還原 base64 字符串:hello, world!

console.log(new Buffer('hello, world!').toString('hex'));
// 轉(zhuǎn)換成十六進制字符串:68656c6c6f2c20776f726c6421

console.log(new Buffer('68656c6c6f2c20776f726c6421', 'hex').toString());
// 還原十六進制字符串:hello, world!

一般情況下,單個 Node.js 進程是有最大內(nèi)存限制的,以下是來自官方文檔中的說明:

What is the memory limit on a node process?

Currently, by default v8 has a memory limit of 512MB on 32-bit systems, and 1.4GB on 64-bit systems. The limit can be raised by setting --max_old_space_size to a maximum of ~1024 (~1 GB) (32-bit) and ~4096 (~4GB) (64-bit), but it is recommended that you split your single process into several workers if you are hitting memory limits.

由于 Buffer 對象占用的內(nèi)存空間是不計算在 Node.js 進程內(nèi)存空間限制上的,因此,我們也常常會使用 Buffer 來存儲需要占用大量內(nèi)存的數(shù)據(jù):

// 分配一個 2G-1 字節(jié)的數(shù)據(jù)
// 單次分配內(nèi)存超過此值會拋出異常 RangeError: Invalid typed array length
var buf = new Buffer(1024 * 1024 * 1024 - 1);

以上便是 Buffer 的幾種常見用法。然而,閱讀 Buffer 的 API 文檔時,我們會發(fā)現(xiàn)更多的是readXXX()writeXXX()開頭的 API,具體如下:

  • buf.readUIntLE(offset, byteLength[, noAssert])

  • buf.readUIntBE(offset, byteLength[, noAssert])

  • buf.readIntLE(offset, byteLength[, noAssert])

  • buf.readIntBE(offset, byteLength[, noAssert])

  • buf.readUInt8(offset[, noAssert])

  • buf.readUInt16LE(offset[, noAssert])

  • buf.readUInt16BE(offset[, noAssert])

  • buf.readUInt32LE(offset[, noAssert])

  • buf.readUInt32BE(offset[, noAssert])

  • buf.readInt8(offset[, noAssert])

  • buf.readInt16LE(offset[, noAssert])

  • buf.readInt16BE(offset[, noAssert])

  • buf.readInt32LE(offset[, noAssert])

  • buf.readInt32BE(offset[, noAssert])

  • buf.readFloatLE(offset[, noAssert])

  • buf.readFloatBE(offset[, noAssert])

  • buf.readDoubleLE(offset[, noAssert])

  • buf.readDoubleBE(offset[, noAssert])

  • buf.write(string[, offset][, length][, encoding])

  • buf.writeUIntLE(value, offset, byteLength[, noAssert])

  • buf.writeUIntBE(value, offset, byteLength[, noAssert])

  • buf.writeIntLE(value, offset, byteLength[, noAssert])

  • buf.writeIntBE(value, offset, byteLength[, noAssert])

  • buf.writeUInt8(value, offset[, noAssert])

  • buf.writeUInt16LE(value, offset[, noAssert])

  • buf.writeUInt16BE(value, offset[, noAssert])

  • buf.writeUInt32LE(value, offset[, noAssert])

  • buf.writeUInt32BE(value, offset[, noAssert])

  • buf.writeInt8(value, offset[, noAssert])

  • buf.writeInt16LE(value, offset[, noAssert])

  • buf.writeInt16BE(value, offset[, noAssert])

  • buf.writeInt32LE(value, offset[, noAssert])

  • buf.writeInt32BE(value, offset[, noAssert])

  • buf.writeFloatLE(value, offset[, noAssert])

  • buf.writeFloatBE(value, offset[, noAssert])

  • buf.writeDoubleLE(value, offset[, noAssert])

  • buf.writeDoubleBE(value, offset[, noAssert])

這些 API 為在 Node.js 中操作數(shù)據(jù)提供了極大的便利。假設(shè)我們要將一個整形數(shù)值存儲到文件中,比如當(dāng)前時間戳為1447656645380,如果將其當(dāng)作一個字符串存儲時,需要占用 11 字節(jié)的空間,而將其轉(zhuǎn)換為二進制存儲時僅需 6 字節(jié)空間即可:

var buf = new Buffer(6);

buf.writeUIntBE(1447656645380, 0, 6);
// 

buf.readUIntBE(0, 6);
// 1447656645380

在使用 Node.js 編寫一些底層功能時,比如一個網(wǎng)絡(luò)通信模塊、某個數(shù)據(jù)庫的客戶端模塊,或者需要從文件中操作大量結(jié)構(gòu)化數(shù)據(jù)時,以上 Buffer 對象提供的 API 都是必不可少的。

接下來將演示一個使用 Buffer 對象操作結(jié)構(gòu)化數(shù)據(jù)的例子。

操作結(jié)構(gòu)化數(shù)據(jù)

假設(shè)有一個學(xué)生考試成績數(shù)據(jù)庫,每條記錄結(jié)構(gòu)如下:

學(xué)號課程代碼分數(shù)
XXXXXXXXXXXX

其中學(xué)號是一個 6 位的數(shù)字,課程代碼是一個 4 位數(shù)字,分數(shù)最高分為 100 分。

在使用文本來存儲這些數(shù)據(jù)時,比如使用 CSV 格式存儲可能是這樣的:

100001,1001,99
100002,1001,67
100003,1001,88

其中每條記錄占用 15 字節(jié)的空間,而使用二進制存儲時其結(jié)構(gòu)將會是這樣:

學(xué)號課程代碼分數(shù)
3 字節(jié)2 字節(jié)1 字節(jié)

每一條記錄僅需要 6 字節(jié)的空間即可,僅僅是使用文本存儲的 40%!下面是用來操作這些記錄的程序:

// 讀取一條記錄
// buf Buffer 對象
// offset 本條記錄在 Buffer 對象的開始位置
// data {number, lesson, score}
function writeRecord (buf, offset, data) {
 buf.writeUIntBE(data.number, offset, 3);
 buf.writeUInt16BE(data.lesson, offset + 3);
 buf.writeInt8(data.score, offset + 5);
}

// 寫入一條記錄
// buf Buffer 對象
// offset 本條記錄在 Buffer 對象的開始位置
function readRecord (buf, offset) {
 return {
 number: buf.readUIntBE(offset, 3),
 lesson: buf.readUInt16BE(offset + 3),
 score: buf.readInt8(offset + 5)
 };
}

// 寫入記錄列表
// list 記錄列表,每一條包含 {number, lesson, score}
function writeList (list) {
 var buf = new Buffer(list.length * 6);
 var offset = 0;
 for (var i = 0; i < list.length; i++) {
 writeRecord(buf, offset, list[i]);
 offset += 6;
 }
 return buf;
}

// 讀取記錄列表
// buf Buffer 對象
function readList (buf) {
 var offset = 0;
 var list = [];
 while (offset < buf.length) {
 list.push(readRecord(buf, offset));
 offset += 6;
 }
 return list;
}

我們可以再編寫一段程序來看看效果:

var list = [
 {number: 100001, lesson: 1001, score: 99},
 {number: 100002, lesson: 1001, score: 88},
 {number: 100003, lesson: 1001, score: 77},
 {number: 100004, lesson: 1001, score: 66},
 {number: 100005, lesson: 1001, score: 55},
];
console.log(list);

var buf = writeList(list);
console.log(buf);
// 輸出 

var ret = readList(buf);
console.log(ret);
/* 輸出
[ { number: 100001, lesson: 1001, score: 99 },
 { number: 100002, lesson: 1001, score: 88 },
 { number: 100003, lesson: 1001, score: 77 },
 { number: 100004, lesson: 1001, score: 66 },
 { number: 100005, lesson: 1001, score: 55 } ]
*/

lei-proto 模塊介紹

上面的例子中,當(dāng)每一條記錄的結(jié)構(gòu)有變化時,我們需要修改readRecord()writeRecord() ,重新計算每一個字段在 Buffer 中的偏移量,當(dāng)記錄的字段比較復(fù)雜時很容易出錯。為此我編寫了lei-proto模塊,它允許你通過簡單定義每條記錄的結(jié)構(gòu)即可生成對應(yīng)的readRecord()`writeRecord()函數(shù)。

首先執(zhí)行以下命令安裝此模塊:

$ npm install lei-proto --save

使用lei-proto模塊后,前文的例子可以改為這樣:

var parsePorto = require('lei-proto');

// 生成指定記錄結(jié)構(gòu)的數(shù)據(jù)編碼/解碼器
var record = parsePorto([
 ['number', 'uint', 3],
 ['lesson', 'uint', 2],
 ['score', 'uint', 1]
]);

function readList (buf) {
 var list = [];
 var offset = 0;
 while (offset < buf.length) {
 list.push(record.decode(buf.slice(offset, offset + 6)));
 offset += 6;
 }
 return list;
}

function writeList (list) {
 return Buffer.concat(list.map(record.encodeEx));
}

運行與上文同樣的測試程序,可看到其結(jié)果是一樣的:


[ { number: 100001, lesson: 1001, score: 99 },
 { number: 100002, lesson: 1001, score: 88 },
 { number: 100003, lesson: 1001, score: 77 },
 { number: 100004, lesson: 1001, score: 66 },
 { number: 100005, lesson: 1001, score: 55 } ]

關(guān)于Buffer怎么在Node.js中使用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


當(dāng)前名稱:Buffer怎么在Node.js中使用
轉(zhuǎn)載注明:http://weahome.cn/article/pdjsgc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部