搜尋
首頁web前端js教程關於Node.js中Buffer的一些被忽略的用法詳解

網路上關於Node.js中Buffer用法的文章有很多,但感覺還是不夠詳細,所以這篇文章主要介紹了關於Node.js中Buffer的一些你可能不知道的用法,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。使用fs模組來

讀取檔案

內容的時候,回傳的就是一個Buffer:

fs.readFile('filename', function (err, buf) {
 // <Buffer 2f 2a 2a 0a 20 2a 20 53 75 ... >
});
在使用net或http模組來接收網路資料時,data事件的參數也是一個Buffer,這時我們還需要使用

Buffer.concat()

來做資料拼接:

var bufs = [];
conn.on(&#39;data&#39;, function (buf) {
 bufs.push(buf);
});
conn.on(&#39;end&#39;, function () {
 // 接收数据结束后,拼接所有收到的 Buffer 对象
 var buf = Buffer.concat(bufs);
});
也可以利用

Buffer.toString()

來做轉換base64或十六進位字元的轉換,例如:

console.log(new Buffer(&#39;hello, world!&#39;).toString(&#39;base64&#39;));
// 转换成 base64 字符串:aGVsbG8sIHdvcmxkIQ==

console.log(new Buffer(&#39;aGVsbG8sIHdvcmxkIQ==&#39;, &#39;base64&#39;).toString());
// 还原 base64 字符串:hello, world!

console.log(new Buffer(&#39;hello, world!&#39;).toString(&#39;hex&#39;));
// 转换成十六进制字符串:68656c6c6f2c20776f726c6421

console.log(new Buffer(&#39;68656c6c6f2c20776f726c6421&#39;, &#39;hex&#39;).toString());
// 还原十六进制字符串:hello, world!
一般情況下,單一Node.js 進程是有最大記憶體限制的,以下是來自官方文件中的說明: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 bebe 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 memory limits.由於Buffer 物件佔用的記憶體空間是不會計算在Node.js 進程記憶體空間限制上的,因此,我們也常常會使用Buffer 來儲存需要佔用大量記憶體的資料:

// 分配一个 2G-1 字节的数据
// 单次分配内存超过此值会抛出异常 RangeError: Invalid typed array length
var buf = new Buffer(1024 * 1024 * 1024 - 1);

以上便是Buffer 的幾種常見用法。然而,閱讀Buffer 的API 文件時,我們會發現更多的是

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 中操作資料提供了極大的便利。假設我們要將一個整形數值儲存到檔案中,例如當前###時間戳###為1447656645380,如果將其當作字串儲存時,需要佔用11 位元組的空間,而將其轉換為二進制儲存時僅需6 位元組空間即可:###
var buf = new Buffer(6);

buf.writeUIntBE(1447656645380, 0, 6);
// <Buffer 01 51 0f 0f 63 04>

buf.readUIntBE(0, 6);
// 1447656645380
###在使用Node.js 編寫一些底層功能時,例如一個網路通訊模組、某個資料庫的客戶端模組,或是需要從檔案中操作大量結構化資料時,以上Buffer 物件提供的API 都是不可或缺的。 ######接下來將示範一個使用 Buffer 物件操作結構化資料的範例。 ###

操作结构化数据

假设有一个学生考试成绩数据库,每条记录结构如下:

学号 课程代码 分数
XXXXXX XXXX XX

其中学号是一个 6 位的数字,课程代码是一个 4 位数字,分数最高分为 100 分。

在使用文本来存储这些数据时,比如使用 CSV 格式存储可能是这样的:

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

其中每条记录占用 15 字节的空间,而使用二进制存储时其结构将会是这样:

学号 课程代码 分数
3 字节 2 字节 1 字节

每一条记录仅需要 6 字节的空间即可,仅仅是使用文本存储的 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);
// 输出 <Buffer 01 86 a1 03 e9 63 01 86 a2 03 e9 58 01 86 a3 03 e9 4d 01 86 a4 03 e9 42 01 86 a5 03 e9 37>

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 模块介绍

上面的例子中,当每一条记录的结构有变化时,我们需要修改readRecord()writeRecord() ,重新计算每一个字段在 Buffer 中的偏移量,当记录的字段比较复杂时很容易出错。为此我编写了lei-proto模块,它允许你通过简单定义每条记录的结构即可生成对应的readRecord()`writeRecord()函数。

首先执行以下命令安装此模块:

$ npm install lei-proto --save

使用lei-proto模块后,前文的例子可以改为这样:

var parsePorto = require(&#39;lei-proto&#39;);

// 生成指定记录结构的数据编码/解码器
var record = parsePorto([
 [&#39;number&#39;, &#39;uint&#39;, 3],
 [&#39;lesson&#39;, &#39;uint&#39;, 2],
 [&#39;score&#39;, &#39;uint&#39;, 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));
}

运行与上文同样的测试程序,可看到其结果是一样的:

<Buffer 01 86 a1 03 e9 63 01 86 a2 03 e9 58 01 86 a3 03 e9 4d 01 86 a4 03 e9 42 01 86 a5 03 e9 37>
[ { 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 } ]

总结

以上是關於Node.js中Buffer的一些被忽略的用法詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境