浅谈节点缓冲模块

浅谈节点缓冲模块
Javascript是unicode编码的数据操作非常友好的客户端,但二进制数据的处理是不满意的。为了处理二进制数据或非Unicode编码的数据,设计了缓冲区类Node.js,实现uint8array界面优化。它的实例与整型数组相似,但其大小在创建后没有调整。在介绍如何使用缓冲区之前,首先介绍了几个知识点。

1,V8引擎的内存使用限制

V8发动机最大堆内存在32位系统默认为512M,在64位系统是1GB,虽然你可以使用的最大空间尺寸参数调整旧的价值,但是当使用缓冲或流大的内存,因为在V8堆缓冲区的内存分配。

2。单个缓冲区实例大小限制

一个缓存实例的最大大小是1gb-1(32位系统)或2gb-1(64位系统)。因此创建缓冲区的情况下,不能超过这个值,或者使用ReadFile()读取大文件方法,否则会抛出rangeerror错误

3、8kb池

NodeJS创建缓冲区实例时,当用户的应用空间超过8KB,可以直接调用内部createUnsafeBuffer()创建一个缓冲区的方法,如果空间是大于0小于4KB,新的缓冲区将在目前的8kb板创建,和剩余空间的更新,为如下图所示:
下面是缓冲区API的简单用法:
1。创建缓冲区实例
使用buffer.from()、Buffer.alloc()、Buffer.allocUnsafe()和创建一个缓冲区实例等方法,6版以前的新缓冲区使用构造函数()已被丢弃,不推荐,因为它可能会导致内存泄漏。

Method Buffer.alloc(大小{,} }填写{,编码),和参数如下:
大小指定缓冲区的长度,但不超过buffer.kmaxlength,如果不是这个号码是错的
填充,指定缓冲区初始化的值,默认值为0。
编码,如果填充是一个字符串,参数指定填充的编码。
如下所示:
const BUF1 = buffer.alloc(10);
console.log(BUF1); / /
const BUF2 = buffer.alloc(10,你好);
console.log(BUF2); / /
const buf3 = buffer.alloc(10,你好,'base64);
console.log(buf3); / /
方法buffer.allocunsafe(大小),尺寸参数指定缓冲区的大小,此方法返回一个未初始化的缓冲区,因此也可以把敏感的数据,由信息的泄漏造成的,建议使用buffer.fill(0)缓冲区初始化函数,和buffer.alloc方法(大小、填充)是不一样的,它可以使用8kb池。以下是用如下:
const buf4 = buffer.allocunsafe(10);
console.log(buf4); / /,可以看到有数据
(0)buf4.fill;
console.log(buf4); / /
Method Buffer.allocUnsafeSlow(大小),这个参数的意义是一样的,这种方法不使用缓冲池,容易造成内存的浪费,使用下面的说明:
const buf5 = buffer.allocunsafeslow(10);
console.log(buf5); / /
方法buffer.from(价值,{…}),这里分为四种情况,如下图所示:
首先,值是一个16进制数组,它将数组转换为缓冲区,如果不是16,它将被转换,如下所示:
const buf6 = buffer.from({ 1,2,3,5,17 });
console.log(buf6); / /
其次,值是一个字符串,而转换字符串是缓冲区,它使用缓冲池,如下所示:
const buf7 = buffer.from('Hello World!;
console.log(buf7); / /
第三,值是一个缓冲区实例,然后将该值复制到新缓冲区,该缓冲区只是值的副本,不共享内存,如下所示:
const buf8 = buffer.from('Hello World);
const buf9 = buffer.from(buf8);
console.log(buf8); / /
console.log(buf9); / /
buf9 { 0 } = 0x66;
console.log(buf8); / /
console.log(buf9); / /
第四、当价值ArrayBuffer,有两个可选参数byteoffset { } { },长度,byteoffset指定位置从ArrayBuffer开始复制和复制,长度长度。如下:
const ARR =新uint8array(2);
ARR { 0 } = 128;
ARR { 1 } = 200;
const buf10 = buffer.from(ARR,0,2);
console.log(buf10); / /
如果引用的是arr.buffer,新创建的缓冲区buf10股ARR的记忆,如下:
const ARR =新uint8array(2);
ARR { 0 } = 128;
ARR { 1 } = 200;
const buf10 = buffer.from(arr.buffer);
ARR { 0 } = 254;
console.log(buf10); / /
2,缓冲区解码
使用的buf.tostring({ { {编码,开始,结束} } })将缓冲区的字符串的方法,编码指定字符编码,默认is'utf8'start结束,起始位置,结束位置(不包括在内),目前只支持encoding'ascii,UTF8,utf16le,UCS2,base64 latin1,二进制,十六进制',用如下:
const buf12 = buffer.from(我爱中国);
console.log(buf12.tostring('base64 ')); / / 5oir54ix5lit5zu9
console.log(buf12.tostring('utf8 ')); / /我爱中国
console.log(buf12.tostring('hex ')); / / e68891e788b1e4b8ade59bbd
3、缓冲拼接、复制、填充、分割
方法buf.fill(价值{,} { } {偏移,最后,编码})用指定的值填充的缓冲区。参数偏移指定填充的起始位置,结束是结束位置,如下所示。
console.log(buffer.allocunsafe(5)。填写('a')。ToString()); / / aaaaa
console.log(buffer.allocunsafe(5)。填写(65),ToString('utf8 ')); / / aaaaa
Methods Buffer.concat(表{,}的总长)缓冲区的多个合并在一起,并返回指定的缓冲区的总长度和总长度的缓冲区参数的一个新实例,如果你不把每个缓冲区长度为内循环的价值功能,然后拼接,所以为了确定最优速度总长度,使用以下:
功能bufferinjoin(buffarr){
var = 0;
BuffArr.forEach((buff,编号,ARR)= > {
Len + = buff.length;
});
VaR缓冲= Buffer.concat(buffarr,Len);
Return buffer;
}
VaR buff = bufferinjoin({ buffer.from('hehe)、Buffer.allocUnsafe(5)。填写(A))));
console.log(黄色); / /
console.log(迷。长度); / / 9
console.log(buff.tostring()); / / heheaaaaa
方法buf.copy(目标对象间复制{ {,} },原sourceend {,})可以复制缓冲区的目标,和参数如下:
目标,复制目标
对象间复制,在复制的目标开始被覆盖
原,在复制源开始复制
SourceEnd,在复制源复制结束的位置

如下所示:

const BUF1 = buffer.from('Hello World!;
const BUF2 = buffer.allocunsafe(5)填充(x);
buf1.copy(buf2,0,0,5);
console.log(buf2.tostring()); / /你好
方法buf.slice({开始} {,}结束)可分为缓冲区,返回一个新的缓冲区,但仍然是原来的参考缓冲器,从而改变了原来的缓冲区的数据,新的缓冲区也将发生变化,如果参数开始,端为负,增加缓冲区的长度第一,然后计算如下:
const BUF1 = buffer.from('Hello World。);
Const buf2 = buf1.slice (0);
console.log(BUF2); / /
BUF2 { 0 } = 88;
console.log(BUF1); / /
const buf3 = buf1.slice(6 - 1);
console.log(buf3.tostring()); / /世界
3、缓冲读写
缓冲区写入操作是在编写开始时通过编写api完成的,主要是以下内容:

Buf.write(字符串{,} { } {偏移量,长度,编码}),写字符串缓冲区
Buf.writeDoubleBE(价值,抵消noassert {,})写64位的浮点数,最终走向
Buf.writeDoubleLE(价值,抵消noassert {,}),写64位浮点数,小端对齐
Buf.writeFloatBE(价值,抵消{,noassert }),写了32个浮点数,最终走向
Buf.writeFloatLE(价值,抵消noassert {,}),写32位浮点数,小端对齐
buf.writeint8(价值,抵消{,noassert }),写一个符号的8位整数
buf.writeint16be(价值,抵消{,noassert }),写一个符号的16位整数,最终走向
buf.writeint16le(价值,抵消{,noassert }),用符号的16位整数,小端对齐
buf.writeint32be(价值,抵消{,noassert }),写一个符号的32位整数,最终走向
buf.writeint32le(价值,抵消{,noassert }),用符号的32位整数,小端对齐
Buf.writeIntBE(值,偏移,bytelength {,noassert }),以下不再累
Buf.writeIntLE(值,偏移,bytelength noassert {,})
buf.writeuint8(价值,抵消noassert {,})
buf.writeuint16be(价值,抵消noassert {,})
buf.writeuint16le(价值,抵消noassert {,})
buf.writeuint32be(价值,抵消noassert {,})
buf.writeuint32le(价值,抵消noassert {,})
Buf.writeUIntBE(值,偏移,bytelength noassert {,})
Buf.writeUIntLE(值,偏移,bytelength noassert {,})
缓冲区读取操作是由api以读开头完成的,主要包括以下内容:

Buf.readDoubleBE(抵消noassert {,})
Buf.readDoubleLE(抵消noassert {,})
Buf.readFloatBE(抵消noassert {,})
Buf.readFloatLE(抵消noassert {,})
buf.readint8(抵消noassert {,})
buf.readint16be(抵消noassert {,})
buf.readint16le(抵消noassert {,})
buf.readint32be(抵消noassert {,})
buf.readint32le(抵消noassert {,})
Buf.readIntBE(偏移,bytelength noassert {,})
Buf.readIntLE(偏移,bytelength noassert {,})
buf.readuint8(抵消noassert {,})
buf.readuint16be(抵消noassert {,})
buf.readuint16le(抵消noassert {,})
buf.readuint32be(抵消noassert {,})
buf.readuint32le(抵消noassert {,})
Buf.readUIntBE(偏移,bytelength noassert {,})
Buf.readUIntLE(偏移,bytelength noassert {,})
使用下面的示例,以32个无符号整数为例:
const buf = buffer.allocunsafe(8);
buf.writeuint32be(0x12345678,0)
console.log(BUF);
const数据= buf.readuint32be(0);
console.log(data.tostring(16));
最后,我们使用缓冲区读取API完成一个小工具,获得PNG格式图片的大小。在开始编码之前,我们首先简要介绍PNG文件的组成。

PNG文件标志
PNG数据块
......
PNG数据块

这里我们使用PNG文件标识符和数据块级的PNG文件头数据块的第一个块,文件识别是固定的8字节,8950 4E 47 0d 0a 1a 0A,IHDR数据块长度为13字节,格式如下:

域名
字节
解释

宽度
4字节
宽度
高度
4字节
高度
位深度
1字节
图像深度
颜色类型
1字节
颜色类型
压缩方法
1字节
压缩方法
滤波器的方法
1字节
滤波器的方法
交错的方法
1字节
隔行扫描的方法
开始编码,如下所示:
const FS =需要('fs);
const路径=需要('path);

const argvs = process.argv.slice(2);
如果(argvs。长度<= 0){
Console.error(请输入图片:png.js img1 IMG2…);
process.exit(- 1);
}
Argvs.forEach((IMG,编号,ARR)= > {
var属性= fs.statsync(IMG);
Fs.open(IMG,R,(呃,FD)= > {
如果(错误)抛出错误;
VaR buff = buffer.alloc(stat.size);
fs.read(FD,浅黄色,0,stat.size,0,(呃,bytesread,缓冲)= > {
如果(错误)抛出错误;
Fs.close(FD),(= > { });
getimgdimension(buff(呃,尺寸)= > {
如果(错误)抛出错误;
console.log(大小` $ { }是{尺寸:IMG美元。宽度} { }尺寸X美元。高度`);
});
});
});
});
功能getimgdimension(buff,CB){
如果((buff.tostring('utf8,1,8)=('png R大')buff.tostring('utf8,12,16)= 'ihdr){)
返回CB(空,{
宽度:buff.readuint32be(16),
身高:buff.readuint32be(20)
},0);
其他{ }
返回CB(新错误(不是PNG图片),1){ }),;
}
}

执行的结果如下:

E: developmentdocument odejsdemo >节点png.js 20160824083157.webp PNG下载

对20160824083157.webp尺寸:195x195

下载的大小。PNG是:720x600
以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部