在大多数介绍Buffer的文章中,主要是围绕数据拼接和内存分配这两方面的。比如我们使用fs模块来读取文件内容的时候,返回的就是一个Buffer:
fs.readFile('filename', function (err, buf) {
//
});
在使用net或http模块来接收网络数据时,data事件的参数也是一个Buffer,这时我们还需要使用Buffer.concat()()来做数据拼接:
var bufs = [];
conn.on('data', function (buf) {
bufs.push(buf);
});
conn.on('end', function () {
// 接收数据结束后,拼接所有收到的Buffer对象
var buf = Buffer.concat(bufs);
});
还可以利用Buffer.toString()来做转换base64或十六进制字符的转换,比如:
console.log(new Buffer('hello, world!').toString('base64'));
// 转换成base64字符串:aGVsbG8sIHdvcmxkIQ==
console.log(new Buffer('aGVsbG8sIHdvcmxkIQ==', 'base64').toString());
// 还原base64字符串:hello, world!
console.log(new Buffer('hello, world!').toString('hex'));
// 转换成十六进制字符串:68656c6c6f2c20776f726c6421
console.log(new Buffer('68656c6c6f2c20776f726c6421', 'hex').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 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对象占用的内存空间是不计算在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);
//
buf.readUIntBE(0, 6);
// 1447656645380
在使用Node.js编写一些底层功能时,比如一个网络通信模块、某个数据库的客户端模块,或者需要从文件中操作大量结构化数据时,以上Buffer对象提供的API都是必不可少的。
node.js是一个运行在chromeJavascript运行环境下(俗称GoogleV8引擎)的开发平台,用来方便快捷的创建服务器端网络应用程序。你可以把它理解为一个轻量级的JSP或PHP环境,但是用来开发Web应用的话,有时要便捷很多。
很多人都不明白,为什么一个javascript的东西用在了服务器端的开发上。一般认为javascript是浏览器端的脚本语言,但是google将其再开发,用来作为服务器端脚本环境,其性能自称比Python、Perl、PHP还要快。
node.js的最大优点是处理并行访问,如果一个web应用程序同时会有很多访问连接,就能体现使用node.js的优势。
另一个好处是,使用javascript作为服务器端脚本语言,可以消除一些与浏览器端js脚本的冲突。甚至发挥javascript动态编程的特性,在服务器与浏览器之间建立直接的动态程序。
总的来说,node.js可以像PHP一样开发动态网站和WEB应用。