node.js的buffer知识点

Buffer与字符编码

介绍

当前buffer和字符串之间转换时,可以指定字符编码。如果未指定字符编码,则使用utf-8作为默认值。

例:

const buf = Buffer.from('hello world', 'utf8');

console.log(buf.toString('hex'));
// 打印: 68656c6c6f20776f726c64
console.log(buf.toString('base64'));
// 打印: aGVsbG8gd29ybGQ=

console.log(Buffer.from('fhqwhgads', 'utf8'));
// 打印: <Buffer 66 68 71 77 68 67 61 64 73>
console.log(Buffer.from('fhqwhgads', 'utf16le'));
// 打印: <Buffer 66 00 68 00 71 00 77 00 68 00 67 00 61 00 64 00 73 00>

Node.js 当前支持的字符编码如下:

‘utf8’: 多字节编码的 Unicode 字符。 许多网页和其他文档格式都使用 UTF-8。 这是默认的字符编码。 当将 Buffer 解码为不专门包含有效 UTF-8 数据的字符串时,则会使用 Unicode 替换字符 U+FFFD � 来表示这些错误。

‘utf16le’: 多字节编码的 Unicode 字符。 与 ‘utf8’ 不同,字符串中的每个字符都会使用 2 个或 4 个字节进行编码。 Node.js 仅支持 UTF-16 的小端序变体。

‘latin1’: Latin-1 代表 ISO-8859-1。 此字符编码仅支持从 U+0000 到 U+00FF 的 Unicode 字符。 每个字符使用单个字节进行编码。 超出该范围的字符会被截断,并映射成该范围内的字符。

使用以上方法之一将 Buffer 转换为字符串,称为解码;将字符串转换为 Buffer,称为编码。

Node.js 还支持以下两种二进制转文本的编码。 对于二进制转文本的编码,其命名约定是相反的:将 Buffer 转换为字符串通常称为编码,而将字符串转换为 Buffer 则称为解码。

‘base64’: Base64 编码。 当从字符串创建 Buffer 时,此编码也会正确地接受 RFC 4648 第 5 节中指定的 “URL 和文件名安全字母”。

‘hex’: 将每个字节编码成两个十六进制的字符。 当解码仅包含有效的十六进制字符的字符串时,可能会发生数据截断。

buffer模块和字符串的区别:

1、buffer内存分配不是在v8的堆内存中,在node中c++层面实现的内存申请
2、buffer形成的字符串是只读的
3、JavaScript适合处理Unicode编码数据,但对二进制数据的处理并不友好。
4、所以处理TCP流或文件系统时,对八位字节流的处理很有必要。
5、Node有几个用于处理,创建和消耗八位字节流的方法。
6、处理的编码类型有:ascii,utf8,utf16le,ucs2(utf16le的别名),base64,binary,hex。
7、Buffer为全局元素,直接new Buffer()就得到一个Buffer实例。

buffer模块

buffer是一种数据传输格式,因为buffer字节在所在语言中都存在,则不需要导入模块

创建一个简单的buffer模块:

let buf = new Buffer('and you')
console.log(buf)
//<Buffer 61 6e 64 20 79 6f 75>
let buf = new Buffer(5)
buf[0] = 0x68;
buf[1] = 0x65;
buf[2] = 0x6c;
buf[3] = 0x6c;
buf[4] = 0x6f;
console.log(buf.toString())//将上面的buffer模块的数组转换成

有上面的代码可以看出来,创建的buffer模块的时候如果括号里面给的是一个字符串的话输出的时候就会变成一个16进制编码组成的数组,而在括号里面传的是一个具体的数,那么也表示这个模块的注册的长度为多长,如果你添加的下标超过了buffer的规定的长度就会添加无效,如果你要讲里面的某一个要改成别的值就只需要指定下标进行重新赋值就行了,但是你从新赋的值要是16进制编码。

buffer模块上常用的api

1、Buffer.alloc(size[, fill[, encoding]])

新建一个Buffer实例,传入的三个参数分别为内存上分配的大小,填充的内容,编码格式,默认为utf8。

console.log(Buffer.alloc(10));//创建⼀一个⻓长度为10的Buffer,默认填充0
console.log(Buffer.alloc(10,2));//创建⼀一个⻓长度为10的Buffer,填充2
console.log(Buffer.alloc(10,100));//创建⼀一个⻓长度为10的Buffer,填充1000
console.log(Buffer.alloc(10,-1));//创建⼀一个⻓长度为10的Buffer,-1强制转换成
255

2、Buffer.allocUnsafe(size) 一般不建议使用

以这种方式创建的 Buffer实例的底层内存是未初始化的。 新创建的 Buffer的内容是未知的,且可能包含敏感数据。
可以使用 buf.fill(0)初始化 Buffer实例为0。

console.log(Buffer.allocUnsafe(10));//创建⼀一个⻓长度为10未初始化的buffer
3、Buffer.from()

参数可以传入一个数组,字符串等等,详细用法见官网api

console.log(Buffer.from('eric')); //创建buffer,填充字符串串
console.log(Buffer.from('eric','base64')); //创建buffer,填充bese64编码的
字符串串
4、Buffer.byteLength(string[, encoding])

返回一个字符串的实际字节长度,第一个参数为要计算长度的值,第二个参数为字符编码,默认为utf8

console.log(Buffer.byteLength('eric'));//返回字符串串的字节⻓长度,4
console.log(Buffer.byteLength('中⽂文'));//6,⼀一个⽂文字代表3个字节
5、Buffer.isBuffer(obj)

判断传入参数是否为一个Buffer对象

console.log(Buffer.isBuffer({}));
console.log(Buffer.isBuffer(Buffer.from('eric')));
6、Buffer.concat(list[, totalLength])

返回一个合并了 list 中所有 Buffer 实例的新建的 Buffer 。
第一个参数是一个数组,例如:[buf1, buf2, buf3]
第二个参数为合并时 list 中 Buffer 实例的总长度。如果没有提供 totalLength ,则从 list 中的 Buffer 实例计算得到。 为了计算 totalLength 会导致需要执行额外的循环,所以提供明确的长度会运行更快。

const buf = Buffer.from('hello');
const buf2 = Buffer.from('eric');
console.log(buf);
console.log(buf2);
console.log(Buffer.concat([buf,buf2]));
console.log(Buffer.concat([buf,buf2],10));

7、buf.length

返回Buffer实例对象在字节数上分配的内存量。 注意,这并不一定反映 buf 内可用的数据量。

8、buf.toString([encoding[, start[, end]]])

根据 encoding 指定的字符编码解码 buf 成一个字符串。 start 和 end 可传入用于只解码 buf 的一部分。

const buf = Buffer.from('test');
console.log(buf.toString('utf8',1,3));
注意:

(node:1416) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
(Use node --trace-deprecation ... to show where the warning was created)
这个是警告,前面使用的方法只有在node 8.2.x以下版本的才有在node 8.2.x以上版本的就没有这样的方法就要使用。Buffer.alloc(), Buffer.allocUnsafe(),Buffer.from()等函数)

解决方案:var buf = Buffer.from(myBase64Str, ‘base64’);

9、buf.fill(value[, offset[, end]][, encoding])

第一个入参value为填充buf的值,
第二和第三个参数为填充起始和结束的位置,如果不传,默认为全部填充。
第四个参数为value的字符编码。

console.log(buf.fill('eric',5,10));
10、buf.equals(otherBuffer)

比较两个Buffer实例对象,如果 buf 与 otherBuffer 具有完全相同的字节,则返回 true,否则返回 false。

const buf1 = Buffer.from('ABC');
const buf2 = Buffer.from('414243', 'hex');
const buf3 = Buffer.from('ABCD');
console.log(buf1);
console.log(buf2);
console.log(buf1.equals(buf2));
// 打印: true
console.log(buf1.equals(buf3));
11、buf.indexOf(value[, byteOffset][, encoding])

第一个参数为需要搜索的值,第二个参数为搜索的起始位置, 默认为0。

12、buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]])

第一个参数为要拷贝进的 Buffer。
第二个参数是目标 buffer 中开始写⼊入之前要跳过的字节数。默认值: 0 。
第三个参数是来源 buffer 中开始拷⻉贝的索引。默认值: 0 。
第四个参数是来源 buffer 中结束拷⻉贝的索引(不不包含)。默认值: buf.length 。

const buf = Buffer.from('abcdefghi');
const buf2 = Buffer.from('test');
// console.log(buf.slice(2,7).toString());
// console.log(buf.copy(buf2));
// console.log(buf2.toString());
console.log(buf2.copy(buf,2,1,3));
console.log(buf.toString());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值