纯JavaScript无法处理二进制数据,buffer就是用来处理二进制数据的

原始数据保存在buffer实例中,一个buffer实例类似于数组。buffer的大小在建立时指定的不可更改。

buffer是一个全局类,不需要使用require来引入。

在buffer和JavaScript string转换时,需要指定编码方式

Class:Buffer

new Buffer(array)

使用字节数组创建一个buffer实例

已弃用 现使用Buffer.from(array)替代

var buf = new Buffer([0x62,0x75,0x66,0x66,0x65,0x72]);
// ['b','u','f','f','e','r']

new Buffer (buffer)

复制一个buffer实例到另一个新创建的buffer中

已弃用 现使用Buffer.from(buffer)替代

const buf1 = new Buffer('buffer');
const buf2 = new Buffer(buf1); buf1[0] = 0x61;//改变buf1'buffer'第一个字符的值
console.log(buf1.toString());
// 'auffer'
console.log(buf2.toString());
// 复制过去的新buffer没有改变

new Buffer(size)

已弃用 现使用Buffer.alloc(size[, fill[, encoding]]) 替代

创建一个大小是size的新的buffer

const buf = new Buffer(5);
console.log(buf);
// <Buffer 78 e0 82 02 01>
// 值不确定
buf.fill(0);//用0填充
console.log(buf);
// <Buffer 00 00 00 00 00>

new Buffer(str[,encoding])

创建一个新的buffer,值为str,编码为encoding

已弃用 现使用Buffer.alloc(size[, fill[, encoding]]) 替代

const buf1 = new Buffer('this is a tést');
console.log(buf1.toString());
// prints: this is a tést
console.log(buf1.toString('ascii'));
// prints: this is a tC)st const buf2 = new Buffer('7468697320697320612074c3a97374', 'hex');
console.log(buf2.toString());
// prints: this is a tést

Class Method:Buffer.alloc(size[, fill[, encoding]])

  • size
  • fill Default: undefined
  • encoding Default: utf8

创建一个size大小的buffer,当fill没有指定时,默认为00

size必须小于等于require('buffer').kMaxLength的值,否则会抛出RangeError错误。

如果fill被指定,将会自动调用buf.fill(fill)

const buf = Buffer.alloc(5, 'a');
console.log(buf);
// <Buffer 61 61 61 61 61>

如果fill和encoding都被指定,将会自动调用buf.fill(fill,encoding)

const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
console.log(buf);
// <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>

Buffer.alloc(size)比Buffer.allocUnsafe(size)慢一些,但创建的数据不会包含敏感数据

当size不是数字是会抛出TypeError错误

Class Method: Buffer.allocUnsafe(size)

  • size

    创建一个size大小的buffer,并且值不确定。为了避免包含敏感数据,请使用buf.fill(0)初始化为0

    size必须小于等于require('buffer').kMaxLength的值,否则会抛出RangeError错误。
const buf = Buffer.allocUnsafe(5);
console.log(buf);
// <Buffer 78 e0 82 02 01>
// (octets will be different, every time)
buf.fill(0);
console.log(buf);
// <Buffer 00 00 00 00 00>

Note that the Buffer module pre-allocates an internal Buffer instance of size Buffer.poolSize that is used as a pool for the fast allocation of new Buffer instances created using Buffer.allocUnsafe(size) (and the deprecated new Buffer(size) constructor) only when size is less than or equal to Buffer.poolSize >> 1 (floor of Buffer.poolSize divided by two). The default value of Buffer.poolSize is 8192 but can be modified.

当有快速的buffer分配时,如果Buffer.allocUnsafe(size)的size小于等于Buffer.poolSize的一半时,Buffer模块会创建一个内部缓冲池。这个缓冲池的默认大小Buffer.poolSize是8192,但他是可修改的

Use of this pre-allocated internal memory pool is a key difference between calling Buffer.alloc(size, fill) vs. Buffer.allocUnsafe(size).fill(fill). Specifically, Buffer.alloc(size, fill) will never use the internal Buffer pool, while Buffer.allocUnsafe(size).fill(fill) will use the internal Buffer pool if size is less than or equal to half Buffer.poolSize. The difference is subtle but can be important when an application requires the additional performance that Buffer.allocUnsafe(size) provides.

使用Buffer.alloc(size,fill)和Buffer.allocUnsafe(size).fill(fill)有一些细微的差别。Buffer.alloc(size,fill)不会使用内部的缓冲池,而Buffer.allocUnsafe(size).fill(fill)在size小于等于Buffer.poolSize的一半时会使用内部缓冲池。这点不同虽然很细微,但如果一个应用需要Buffer.allocUnsafe(size)提供的这一点额外性能的话,它还是很关键的.

Class Method: Buffer.allocUnsafeSlow(size)

  • size

Allocates a new non-zero-filled and non-pooled Buffer of size bytes. The size must be less than or equal to the value of require('buffer').kMaxLength (on 64-bit architectures, kMaxLength is (2^31)-1). Otherwise, a RangeError is thrown. A zero-length Buffer will be created if a size less than or equal to 0 is specified.

The underlying memory for Buffer instances created in this way is not initialized. The contents of the newly created Buffer are unknown and may contain sensitive data. Use buf.fill(0) to initialize such Buffer instances to zeroes.

When using Buffer.allocUnsafe() to allocate new Buffer instances, allocations under 4KB are, by default, sliced from a single pre-allocated Buffer. This allows applications to avoid the garbage collection overhead of creating many individually allocated Buffers. This approach improves both performance and memory usage by eliminating the need to track and cleanup as many Persistent objects.

However, in the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate to create an un-pooled Buffer instance using Buffer.allocUnsafeSlow() then copy out the relevant bits.

// need to keep around a few small chunks of memory
const store = []; socket.on('readable', () => {
const data = socket.read();
// allocate for retained data
const sb = Buffer.allocUnsafeSlow(10);
// copy the data into the new allocation
data.copy(sb, 0, 0, 10);
store.push(sb);
});

Use of Buffer.allocUnsafeSlow() should be used only as a last resort after a developer has observed undue memory retention in their applications.

Class Method: Buffer.byteLength(string[, encoding])

  • string | | | |
  • encoding Default: 'utf8'
  • Return:

将会返回这个字符串真实byte长度。这个和String.prototype.length是不一样的,因为那个方法返回这个字符串中有几个字符的数量。

const str = '\u00bd + \u00bc = \u00be';

console.log(`${str}: ${str.length} characters, ` +
`${Buffer.byteLength(str, 'utf8')} bytes`); // ½ + ¼ = ¾: 9 characters, 12 bytes

Class Method: Buffer.compare(buf1, buf2)

  • buf1
  • buf2
  • Return:

    返回一个数字,表示 buf 在 otherBuffer 之前(<0),之后(>0)或相同(==0)。这个方法和buf1.compare(buf2)相同。
const arr = [Buffer.from('1234'), Buffer.from('0123')];
arr.sort(Buffer.compare);

Class Method: Buffer.concat(list[, totalLength])

  • list List of Buffer objects to concat
  • totalLength list中buffer的长度而不是个数
  • Return:

    把list中的全部buffer连接在一起后返回这个新的buffer3

如果list中没有buffer或者total length为0,将返回一个长度为0的buffer

如果没有提供totalLength的值,将会自动计算list中buffer的长度,但是直接给出会更快。

const buf1 = Buffer.alloc(10);
const buf2 = Buffer.alloc(14);
const buf3 = Buffer.alloc(18);
const totalLength = buf1.length + buf2.length + buf3.length; console.log(totalLength);
const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
console.log(bufA);
console.log(bufA.length); // 42
// <Buffer 00 00 00 00 ...>
// 42

Class Method: Buffer.from(array)

  • array

使用array里的字节创建一个新的buffer

const buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]);
// creates a new Buffer containing ASCII bytes
// ['b','u','f','f','e','r']

如果array不是Array 抛出TypeArray错误

Class Method: Buffer.from(arrayBuffer[, byteOffset[, length]])

  • arrayBuffer 一个 TypedArray的buffer属性(.buffer)或者一个new ArrayBuffer()

When passed a reference to the .buffer property of a TypedArray instance, the newly created Buffer will share the same allocated memory as the TypedArray.

当传递一个TypedArray实例的.buffer属性时,新创建的buffer会和这个实例共享内存

const arr = new Uint16Array(2);
arr[0] = 5000;
arr[1] = 4000; const buf = Buffer.from(arr.buffer); // shares the memory with arr; console.log(buf);
// Prints: <Buffer 88 13 a0 0f> // changing the TypedArray changes the Buffer also
arr[1] = 6000; console.log(buf);
// Prints: <Buffer 88 13 70 17>

当 arrayBuffer不是TypedArray类型是抛出TypeError错误

Class Method: Buffer.from(buffer)

  • buffer

复制这个buffer参数到一个新的buffer实例中

const buf1 = Buffer.from('buffer');
const buf2 = Buffer.from(buf1); buf1[0] = 0x61;
console.log(buf1.toString());
// 'auffer'
console.log(buf2.toString());
// 'buffer' (copy is not changed)

当buffer不是Buffer类型时抛出TypeError错误

Class Method: Buffer.from(str[, encoding])

  • str String to encode.
  • encoding Encoding to use, Default: 'utf8'

创建一个包含给出的str的buffer实例,如果给定了encoding参数,将转换为这个参数,如果没有给定,默认为utf-8。

const buf1 = Buffer.from('this is a tést');
console.log(buf1.toString());
// prints: this is a tést
console.log(buf1.toString('ascii'));
// prints: this is a tC)st const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
console.log(buf2.toString());
// prints: this is a tést

如果str不是String类型将抛出TypeError错误

Class Method: Buffer.isBuffer(obj)

  • obj
  • Return:

当obj是一个Buffer是返回true

Class Method: Buffer.isEncoding(encoding)

  • encoding The encoding string to test
  • Return:

当encoding是一个有效地参数时返回true,否则false

buf[index]

获取或者设置在指定index索引位置的8位字节。这个值是指单个字节,所以这个值必须在合法的范围,16进制的0x00 到0xFF,或者0 到255。

const str = "Node.js";
const buf = new Buffer(str.length); for (var i = 0; i < str.length ; i++) {
buf[i] = str.charCodeAt(i);
} console.log(buf.toString('ascii'));
// Prints: Node.js

buf.compare(otherBuffer)

  • otherBuffer
  • Return:

比较两个Buffer实例并返回一个数值

  • 0 当buf和otherBuffer相等时
  • -1 当buf应该在otherBuffer之前时
  • 1 当buf应该在otherBuffer之后时
onst buf1 = new Buffer('ABC');
const buf2 = new Buffer('BCD');
const buf3 = new Buffer('ABCD'); console.log(buf1.compare(buf1));
// Prints: 0
console.log(buf1.compare(buf2));
// Prints: -1
console.log(buf1.compare(buf3));
// Prints: 1
console.log(buf2.compare(buf1));
// Prints: 1
console.log(buf2.compare(buf3));
// Prints: 1 [buf1, buf2, buf3].sort(Buffer.compare);
// produces sort order [buf1, buf3, buf2]

buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]])

-targetBuffer Buffer to copy into

  • targetStart Default: 0
  • sourceStart Default: 0
  • sourceEnd Default: buffer.length
  • Return: The number of bytes copied.

把buf的数据复制给targetBuffer,即使他们有重叠的区域

const buf1 = new Buffer(26);
const buf2 = new Buffer(26).fill('!'); for (var i = 0 ; i < 26 ; i++) {
buf1[i] = i + 97; // 97 is ASCII a
} buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));
// Prints: !!!!!!!!qrst!!!!!!!!!!!!!
const buf = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97; // 97 is ASCII a
} buf.copy(buf, 0, 4, 10);
console.log(buf.toString()); // efghijghijklmnopqrstuvwxyz

buf.entries()

创建并返回 [index,byte] 索引/值 对

const buf = new Buffer('buffer');
for (var pair of buf.entries()) {
console.log(pair);
}
// prints:
// [0, 98]
// [1, 117]
// [2, 102]
// [3, 102]
// [4, 101]
// [5, 114]

buf.equals(otherBuffer)

  • otherBuffer
  • Return:

判断buf和otherBuffer是否完全相等,返回布尔值

const buf1 = new Buffer('ABC');
const buf2 = new Buffer('414243', 'hex');
const buf3 = new Buffer('ABCD'); console.log(buf1.equals(buf2));
// Prints: true
console.log(buf1.equals(buf3));
// Prints: false

buf.fill(value[, offset[, end]])#

  • value |
  • offset Default: 0
  • end Default: buffer.length
  • Return:

用指定的值填满buffer ,如果没有给定offset和end的值,将默认填满整个buffer。因为这个方法会返回指向这个buffer的指针,可以用链式写法

const b = new Buffer(50).fill('h');
console.log(b.toString());
// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

buf.indexOf(value[, byteOffset][, encoding])#

  • value | |
  • byteOffset Default: 0
  • encoding Default: 'utf8'
  • Return:

功能和JavaScript中Array.indexOf()一样。

const buf = new Buffer('this is a buffer');

buf.indexOf('this');
// returns 0
buf.indexOf('is');
// returns 2
buf.indexOf(new Buffer('a buffer'));
// returns 8
buf.indexOf(97); // ascii for 'a'
// returns 8
buf.indexOf(new Buffer('a buffer example'));
// returns -1
buf.indexOf(new Buffer('a buffer example').slice(0,8));
// returns 8 const utf16Buffer = new Buffer('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); utf16Buffer.indexOf('\u03a3', 0, 'ucs2');
// returns 4
utf16Buffer.indexOf('\u03a3', -4, 'ucs2');
// returns 6

buf.keys()

Return:

创建并返回一个index迭代

const buf = new Buffer('buffer');
for (var key of buf.keys()) {
console.log(key);
}
// prints:
// 0
// 1
// 2
// 3
// 4
// 5

buf.values()

Return:

创建并返回一个value迭代

const buf = new Buffer('buffer');
for (var value of buf.values()) {
console.log(value);
}
// prints:
// 98
// 117
// 102
// 102
// 101
// 114 for (var value of buf) {
console.log(value);
}
// prints:
// 98
// 117
// 102
// 102
// 101
// 114

buf.length

返回buffer分配的内存的大小,而不是这个buffer包含内容的大小

const buf = new Buffer(1234);

console.log(buf.length);
// Prints: 1234 buf.write('some string', 0, 'ascii');
console.log(buf.length);
// Prints: 1234

虽然length不是不变的,但改变他的值可能会引起一些不可预料的情况,因此我们应当把他当成只读的,如果要修改请使用buffer.slice()创建一个新的buffer。

var buf = new Buffer(10);
buf.write('abcdefghj', 0, 'ascii');
console.log(buf.length);
// Prints: 10
buf = buf.slice(0,5);
console.log(buf.length);
// Prints: 5

buf.slice([start[, end]])#

  • start Default: 0
  • end Default: buffer.length
  • Return:

返回一个新的buffer,这个buffer将会和老的buffer引用相同的内存地址,只是根据 start (默认是 0) 和end (默认是buffer.length) 偏移和裁剪了索引。

包含开头不含结尾

const buf1 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
buf1[i] = i + 97; // 97 is ASCII a
} const buf2 = buf1.slice(0, 3);
buf2.toString('ascii', 0, buf2.length);
// Returns: 'abc'
buf1[0] = 33;
buf2.toString('ascii', 0, buf2.length);
// Returns : '!bc'

负的索引是从buffer尾部开始计算的(相当于加上buffer.length)。

const buf = new Buffer('buffer');

buf.slice(-6, -1).toString();
// Returns 'buffe', equivalent to buf.slice(0, 5)
buf.slice(-6, -2).toString();
// Returns 'buff', equivalent to buf.slice(0, 4)
buf.slice(-5, -2).toString();
// Returns 'uff', equivalent to buf.slice(1, 4)

buf.toString([encoding[, start[, end]]])#

  • encoding Default: 'utf8'
  • start Default: 0
  • end Default: buffer.length
  • Return:

把buffer中的数据以用encoding解码并以字符串的方式返回

const buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97; // 97 is ASCII a
}
buf.toString('ascii');
// Returns: 'abcdefghijklmnopqrstuvwxyz'
buf.toString('ascii',0,5);
// Returns: 'abcde'
buf.toString('utf8',0,5);
// Returns: 'abcde'
buf.toString(undefined,0,5);
// Returns: 'abcde', encoding defaults to 'utf8'

buf.toJSON()

Return:

返回这个buffer实例的JSON序列,JSON.stringify()在字符串化buffer实例时隐式调用了这个方法

const buf = new Buffer('test');
const json = JSON.stringify(buf); console.log(json);
// Prints: '{"type":"Buffer","data":[116,101,115,116]}' const copy = JSON.parse(json, (key, value) => {
return value && value.type === 'Buffer'
? new Buffer(value.data)
: value;
}); console.log(copy.toString());
// Prints: 'test'

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

string Bytes to be written to buffer

offset Default: 0

length Default: buffer.length - offset

encoding Default: 'utf8'

Return: Numbers of bytes written

根据参数 offset 偏移量和指定的encoding编码方式,将参数 string 数据写入buffer。 offset偏移量 默认是 0, encoding编码方式默认是 'utf8'。 length长度是将要写入的字符串的bytes大小。 返回number类型,表示多少8位字节流被写入了。如果buffer 没有足够的空间来放入整个string,它将只会写入部分的字符串。 length 默认是 buffer.length - offset

const buf = new Buffer(256);
const len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
// Prints: 12 bytes: ½ + ¼ = ¾

nodejs系列笔记01---Buffer的更多相关文章

  1. 【NodeJS 学习笔记01】不学就老了

    前言 再不学nodeJs,我们就老了......在HTML5大浪袭来的时候,很多先辈就开始了NodeJs之旅,而那时我还在做服务器端的程序后来转成前端,和梯队的距离已经很大了,因为我会服务器端语言,还 ...

  2. nodejs系列笔记02---模块路径解析

    模块路径解析规则 参考这篇博客 我们已经知道,require函数支持斜杠(/)或盘符(C:)开头的绝对路径,也支持./开头的相对路径.但这两种路径在模块之间建立了强耦合关系,一旦某个模块文件的存放位置 ...

  3. 高级Bash Scripting系列笔记--01之“什么情况不适用Bash Script”

      1. 占用资源的任务,尤其那些影响速度的工作 比如排序,哈希,递归等等. 2. 大量使用数学运算 尤其是浮点运算,比如任意精度的计算或者复数计算等等,这类使用C++会好很多. 3. 跨平台的(适用 ...

  4. 啃掉Hadoop系列笔记(01)-Hadoop框架的大数据生态

    一.Hadoop是什么 1)Hadoop是一个由Apache基金会所开发的分布式系统基础架构 2)主要解决,海量数据的存储和海量数据的分析计算问题. 3)广义上来说,HADOOP通常是指一个更广泛的概 ...

  5. Nodejs学习笔记(六)—Node.js + Express 构建网站预备知识

    前言 前面经过五篇Node.js的学习,基本可以开始动手构建一个网站应用了,先用这一篇了解一些构建网站的知识! 主要是些基础的东西... 如何去创建路由规则.如何去提交表单并接收表单项的值.如何去给密 ...

  6. Java系列笔记(4) - JVM监控与调优

    目录 参数设置收集器搭配启动内存分配监控工具和方法调优方法调优实例     光说不练假把式,学习Java GC机制的目的是为了实用,也就是为了在JVM出现问题时分析原因并解决之.通过学习,我觉得JVM ...

  7. Java系列笔记(3) - Java 内存区域和GC机制

    目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbage Collection, ...

  8. Java系列笔记(6) - 并发(上)

    目录 1,基本概念 2,volatile 3,atom 4,ThreadLocal 5,CountDownLatch和CyclicBarrier 6,信号量 7,Condition 8,Exchang ...

  9. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

随机推荐

  1. 解决python pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query')

    解决python pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query') 学习了:ht ...

  2. js 实现存储Map 结构的数据

    <script type="text/javascript"> function Map() { var struct = function(key, value) { ...

  3. 向大家推荐两个灰常好用的插件LigerUI和报表控件highcharts

    废话不多说上一张图看看,向大家推荐两个灰常好用的插件LigerUI和报表控件highcharts.欢迎大家进技术群讨论:QQ群:15129679 http://ligerui.com/和http:// ...

  4. linux最常用命令整理

    linux vim命令跳转到文档开头或末尾 gg:命令将光标移动到文档开头 G:命令将光标移动到文档末尾 <hr/> 网络 # ifconfig # 查看所有网络接口的属性 # iptab ...

  5. Win7盗版提示,屏幕右下角出现 Windows内部版本7601此Windows副本不是正版怎么办

    Windows7 屏幕右下角出现 Windows内部版本7601此Windows副本不是正版 有很多人反应windows7会出现提示"Win7内部版本7600此Windows副本不是正版&q ...

  6. CF无法全屏怎么办

    方法1:把桌面的分辨率调成800X600,然后运行CF就全屏了,接着再退出游戏,把桌面重新调回原来的分辨率. 方法2:在运行中输入regedit.可以打开打开注册表编辑器,定位到HKEY_LOCAL_ ...

  7. C#时间的味道——任时光匆匆我只在乎你

    如果没有遇见你,我将会是在哪里?日子过的怎么样人生是否要珍惜...任时光匆匆我只在乎你,心甘情愿感染你的气息,人生几何能得到知己...一首邓丽君的<我只在乎你>不禁令我唏嘘不已,这些年离我 ...

  8. python之sqlalchemy基本

    一.SQLAlchemy 1.sqlalchemy是一个ORM框架,它本身无法操作数据库,需要依赖pymysql.MySQLdb,mssql等第三方插件 2.安装: pip install SQLAl ...

  9. 极光推送sdk使用

    创建应用 进入极光控制台后,点击“创建应用”按钮,进入创建应用的界面. 填上你的应用程序的名称以及应用包名这二项就可以了, 最后点击最下方的 “创建我的应用”按钮,创建应用完毕.   创建应用   填 ...

  10. RAC环境下的堵塞(blocking blocked)

    RAC环境下的堵塞不同于单实例情形,由于我们须要考虑到位于不同实例的session.也就是说之前查询的v$session,v$lock对应的应变化为全局范围来查找.本文提供了2个查询脚本,并给出实例演 ...