이 글에서는 Nodejs 버퍼 모듈의 공통 API에 대해 자세히 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
Buffer는 노드의 핵심 모듈입니다. 개발자는 이를 사용하여 파일 스트림 읽기 및 쓰기, 네트워크 요청 데이터 처리 등의 바이너리 데이터를 처리할 수 있습니다.
Buffer에는 많은 API가 있습니다. 이 기사에서는 생성, 비교, 연결, 복사, 검색, 순회, 유형 변환, 가로채기, 인코딩 변환 등을 포함하여 더 일반적으로 사용되며 이해하기 쉬운 API만 선택합니다. 버퍼 인스턴스. [추천 학습: "nodejs 튜토리얼"]
// Creates a new Buffer containing the ASCII bytes of the string 'buffer' const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
확인:
var array = 'buffer'.split('').map(function(v){ return '0x' + v.charCodeAt(0).toString(16) }); console.log( array.join() ); // 输出:0x62,0x75,0x66,0x66,0x65,0x72
var buf1 = Buffer.alloc(10); // 长度为10的buffer,初始值为0x0 var buf2 = Buffer.alloc(10, 1); // 长度为10的buffer,初始值为0x1
var buf3 = Buffer.allocUnsafe(10); // 长度为10的buffer,初始值不确定
var buf4 = Buffer.from([1, 2, 3]) // 长度为3的buffer,初始值为 0x01, 0x02, 0x03
예 1: Buffer.from(배열)
르레에예제 2: Buffer.from(string[, 인코딩])
문자열을 통해 버퍼를 생성합니다. 버퍼를 문자열로 변환할 때 인코딩을 일관되게 유지해야 합니다. 그렇지 않으면 아래와 같이 잘못된 문자가 나타납니다.
// [0x62, 0x75, 0x66, 0x66, 0x65, 0x72] 为字符串 "buffer" // 0x62 为16进制,转成十进制就是 98,代表的就是字母 b var buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); console.log(buf.toString());
깨진 문자 분석은 다음과 같습니다.
var buf = Buffer.from('this is a tést'); // 默认采用utf8 // 输出:this is a tést console.log(buf.toString()); // 默认编码是utf8,所以正常打印 // 输出:this is a tC)st console.log(buf.toString('ascii')); // 转成字符串时,编码不是utf8,所以乱码
예제 3: Buffer.from(buffer)
새 Buffer 인스턴스를 생성하고 버퍼 데이터를 새 인스턴스에 복사합니다.
var letter = 'é'; var buff = Buffer.from(letter); // 默认编码是utf8,这里占据两个字节 <Buffer c3 a9> var len = buff.length; // 2 var code = buff[0]; // 第一个字节为0xc3,即195:超出ascii的最大支持范围 var binary = code.toString(2); // 195的二进制:10101001 var finalBinary = binary.slice(1); // 将高位的1舍弃,变成:0101001 var finalCode = parseInt(finalBinary, 2); // 0101001 对应的十进制:67 var finalLetter = String.fromCharCode(finalCode); // 67对应的字符:C // 同理 0xa9最终转成的ascii字符为) // 所以,最终输出为 this is a tC)st
두 버퍼 인스턴스에 저장된 데이터가 동일한지 확인하면 true를 반환하고, 그렇지 않으면 false를 반환합니다.
var buff = Buffer.from('buffer'); var buff2 = Buffer.from(buff); console.log(buff.toString()); // 输出:buffer console.log(buff2.toString()); // 输出:buffer buff2[0] = 0x61; console.log(buff.toString()); // 输出:buffer console.log(buff2.toString()); // 输出:auffer
는 또한 두 개의 버퍼 인스턴스를 비교합니다. 차이점은 다음과 같습니다.
특정 비교를 지정할 수 있습니다. 범위 (시작 및 끝으로 지정)
반환 값은 정수이며 buf와 대상 간의 크기 관계는 표준
에 도달합니다. 반환 값은
0</code이라고 가정합니다. >: buf, 대상 크기가 동일합니다. <code>0
:buf、target大小相同。1
:buf大于target,也就是说buf应该排在target之后。-1
:buf小于target,也就是说buf应该排在target之前。看例子,官方的例子挺好的,直接贴一下:
// 例子一:编码一样,内容相同 var buf1 = Buffer.from('A'); var buf2 = Buffer.from('A'); console.log( buf1.equals(buf2) ); // true // 例子二:编码一样,内容不同 var buf3 = Buffer.from('A'); var buf4 = Buffer.from('B'); console.log( buf3.equals(buf4) ); // false // 例子三:编码不一样,内容相同 var buf5 = Buffer.from('ABC'); // <Buffer 41 42 43> var buf6 = Buffer.from('414243', 'hex'); console.log(buf5.equals(buf6)); //true //只要比较的两者内容相同,`buf.equals(otherBuffer)` 就返回true
跟 buf.compare(target)
大同小异,一般用于排序。直接贴官方例子:
const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('BCD'); const buf3 = Buffer.from('ABCD'); // Prints: 0 console.log(buf1.compare(buf1)); // Prints: -1 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: [ <Buffer 41 42 43>, <Buffer 41 42 43 44>, <Buffer 42 43 44> ] // (This result is equal to: [buf1, buf3, buf2]) console.log([buf1, buf2, buf3].sort(Buffer.compare));
这里稍微研究下Buffer.from(array)。下面是官方文档对API的说明,也就是说,每个array的元素对应1个字节(8位),取值从0到255。
Allocates a new Buffer using an array of octets.
首先看下,传入的元素为数字的场景。下面分别是10进制、8进制、16进制,跟预期中的结果一致。
const buf1 = Buffer.from('1234'); const buf2 = Buffer.from('0123'); const arr = [buf1, buf2]; // Prints: [ <Buffer 30 31 32 33>, <Buffer 31 32 33 34> ] // (This result is equal to: [buf2, buf1]) console.log(arr.sort(Buffer.compare));
var buff = Buffer.from([62]) // <Buffer 3e> // buff[0] === parseInt('3e', 16) === 62
var buff = Buffer.from([062]) // <Buffer 32> // buff[0] === parseInt(62, 8) === parseInt(32, 16) === 50
再看下,传入的元素为字符串的场景。
0
开头的字符串,在parseInt('062')时,可以解释为62,也可以解释为50(八进制),这里看到采用了第一种解释。
字符串的场景,跟parseInt()有没有关系,暂未深入探究,只是这样猜想。TODO(找时间研究下)
var buff = Buffer.from([0x62]) // <Buffer 62> // buff[0] === parseInt(62, 16) === 98
var buff = Buffer.from(['62']) // <Buffer 3e> // buff[0] === parseInt('3e', 16) === parseInt('62') === 62
var buff = Buffer.from(['062']) // <Buffer 3e> // buff[0] === parseInt('3e', 16) === parseInt('062') === 62
感兴趣的同学自行探究。
var buff = Buffer.from(['0x62']) // <Buffer 62> // buff[0] === parseInt('62', 16) === parseInt('0x62') === 98
一开始不自觉的会将Buffer.from('1')[0]
跟"1"
划等号,其实"1"
对应的编码是49。
var buff = Buffer.from([256]) // <Buffer 00>
这样对比就知道了,编码为1的是个控制字符,表示 Start of Heading。
var buff = Buffer.from('1') // <Buffer 31> console.log(buff[0] === 1) // false
备注:个人觉得totalLength
1
: buf는 target보다 큽니다. 즉, buf는 target 다음에 순위가 매겨져야 함을 의미합니다. -1
: buf는 대상보다 작습니다. 이는 buf가 대상보다 먼저 순위가 지정되어야 함을 의미합니다. 🎜🎜🎜예를 보세요. 공식 예는 꽤 좋습니다. 그냥 붙여넣으세요. 🎜console.log( String.fromCharCode(49) ) // '1' console.log( String.fromCharCode(1) ) // '\u0001'
buf .compare(대상)
은 유사하며 일반적으로 정렬에 사용됩니다. 공식 예제를 직접 게시하세요: 🎜var buff1 = Buffer.alloc(10); var buff2 = Buffer.alloc(20); var totalLength = buff1.length + buff2.length; console.log(totalLength); // 30 var buff3 = Buffer.concat([buff1, buff2], totalLength); console.log(buff3.length); // 30
🎜옥텟 배열을 사용하여 새 버퍼를 할당합니다.🎜
var buff4 = Buffer.from([1, 2]); var buff5 = Buffer.from([3, 4]); var buff6 = Buffer.concat([buff4, buff5], 5); console.log(buff6.length); // console.log(buff6); // <Buffer 01 02 03 04 00> var buff7 = Buffer.concat([buff4, buff5], 3); console.log(buff7.length); // 3 console.log(buff7); // <Buffer 01 02 03>
var buff1 = Buffer.from([1, 2]); var buff2 = Buffer.alloc(2); buff1.copy(buff2); console.log(buff2); // <Buffer 01 02>
const buf1 = Buffer.allocUnsafe(26); const buf2 = Buffer.allocUnsafe(26).fill('!'); for (let i = 0 ; i < 26 ; i++) { // 97 is the decimal ASCII value for 'a' buf1[i] = i + 97; } buf1.copy(buf2, 8, 16, 20); // Prints: !!!!!!!!qrst!!!!!!!!!!!!! console.log(buf2.toString('ascii', 0, 25));
0
으로 시작하는 문자열은 62 또는 50(8진수)으로 해석될 수 있습니다. 여기서는 첫 번째 해석이 사용되는 것을 볼 수 있습니다. 🎜🎜🎜🎜문자열 시나리오가parseInt()와 관련이 있는지 여부는 아직 깊이 조사되지 않았으며 단지 추측일 뿐입니다. TODO (공부할 시간 찾기)🎜🎜🎜const buf = Buffer.from('this is a buffer'); // Prints: 0 console.log(buf.indexOf('this')); // Prints: 2 console.log(buf.indexOf('is')); // Prints: 8 console.log(buf.indexOf(Buffer.from('a buffer'))); // Prints: 8 // (97 is the decimal ASCII value for 'a') console.log(buf.indexOf(97)); // Prints: -1 console.log(buf.indexOf(Buffer.from('a buffer example'))); // Prints: 8 console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8))); const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); // Prints: 4 console.log(utf16Buffer.indexOf('\u03a3', 0, 'ucs2')); // Prints: 6 console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2'));
var buff = Buffer.alloc(4); buff.write('a'); // 返回 1 console.log(buff); // 打印 <Buffer 61 00 00 00> buff.write('ab'); // 返回 2 console.log(buff); // 打印 <Buffer 61 62 00 00>
var buff = Buffer.alloc(20).fill('a'); console.log(buff.toString()); // aaaaaaaaaaaaaaaaaaaa
var buff = Buffer.from('hello'); console.log( buff.toString() ); // hello console.log( buff.toString('utf8', 0, 2) ); // he
Buffer.from('1')[0]
등호 < code>"1"입니다. 실제로 "1"
에 해당하는 코드는 49입니다. 🎜var buff = Buffer.from('hello'); console.log( buff.toJSON() ); // { type: 'Buffer', data: [ 104, 101, 108, 108, 111 ] }
var buff = Buffer.from('abcde'); for(const key of buff.keys()){ console.log('key is %d', key); } // key is 0 // key is 1 // key is 2 // key is 3 // key is 4 for(const value of buff.values()){ console.log('value is %d', value); } // value is 97 // value is 98 // value is 99 // value is 100 // value is 101 for(const pair of buff.entries()){ console.log('buff[%d] === %d', pair[0], pair[1]); } // buff[0] === 97 // buff[1] === 98 // buff[2] === 99 // buff[3] === 100 // buff[4] === 101
totalLength
매개변수는 상당히 중복된다고 생각합니다. 공식문서에 따르면 성능향상 측면에서 고려되고 있다. 그러나 내부 구현에서는 목록을 순회하고 길이를 누적하여 totalLength를 얻습니다. 이러한 관점에서 성능 최적화는 거의 무시할 수 있습니다. 🎜var buff1 = Buffer.from('abcde'); console.log(buff1); // <Buffer 61 62 63 64 65> var buff2 = buff1.slice(); console.log(buff2); // <Buffer 61 62 63 64 65> var buff3 = buff1.slice(1, 3); console.log(buff3); // <Buffer 62 63> buff3[0] = 97; // parseInt(61, 16) ==> 97 console.log(buff1); // <Buffer 62 63>
var buff4 = Buffer.from([1, 2]); var buff5 = Buffer.from([3, 4]); var buff6 = Buffer.concat([buff4, buff5], 5); console.log(buff6.length); // console.log(buff6); // <Buffer 01 02 03 04 00> var buff7 = Buffer.concat([buff4, buff5], 3); console.log(buff7.length); // 3 console.log(buff7); // <Buffer 01 02 03>
使用比较简单,如果忽略后面三个参数,那就是将buf的数据拷贝到target里去,如下所示:
var buff1 = Buffer.from([1, 2]); var buff2 = Buffer.alloc(2); buff1.copy(buff2); console.log(buff2); // <Buffer 01 02>
另外三个参数比较直观,直接看官方例子
const buf1 = Buffer.allocUnsafe(26); const buf2 = Buffer.allocUnsafe(26).fill('!'); for (let i = 0 ; i < 26 ; i++) { // 97 is the decimal ASCII value for 'a' buf1[i] = i + 97; } buf1.copy(buf2, 8, 16, 20); // Prints: !!!!!!!!qrst!!!!!!!!!!!!! console.log(buf2.toString('ascii', 0, 25));
跟数组的查找差不多,需要注意的是,value可能是String、Buffer、Integer中的任意类型。
另外,可以通过byteOffset
来指定起始查找位置。
直接上代码,官方例子妥妥的,耐心看完它基本就理解得差不多了。
const buf = Buffer.from('this is a buffer'); // Prints: 0 console.log(buf.indexOf('this')); // Prints: 2 console.log(buf.indexOf('is')); // Prints: 8 console.log(buf.indexOf(Buffer.from('a buffer'))); // Prints: 8 // (97 is the decimal ASCII value for 'a') console.log(buf.indexOf(97)); // Prints: -1 console.log(buf.indexOf(Buffer.from('a buffer example'))); // Prints: 8 console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8))); const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); // Prints: 4 console.log(utf16Buffer.indexOf('\u03a3', 0, 'ucs2')); // Prints: 6 console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2'));
将sring写入buf实例,同时返回写入的字节数。
参数如下:
看个简单例子
var buff = Buffer.alloc(4); buff.write('a'); // 返回 1 console.log(buff); // 打印 <Buffer 61 00 00 00> buff.write('ab'); // 返回 2 console.log(buff); // 打印 <Buffer 61 62 00 00>
用value
填充buf,常用于初始化buf。参数说明如下:
value
是String,那么为value
的编码,默认是utf8。例子:
var buff = Buffer.alloc(20).fill('a'); console.log(buff.toString()); // aaaaaaaaaaaaaaaaaaaa
把buf解码成字符串,用法比较直观,看例子
var buff = Buffer.from('hello'); console.log( buff.toString() ); // hello console.log( buff.toString('utf8', 0, 2) ); // he
var buff = Buffer.from('hello'); console.log( buff.toJSON() ); // { type: 'Buffer', data: [ 104, 101, 108, 108, 111 ] }
用于对buf
进行for...of
遍历,直接看例子。
var buff = Buffer.from('abcde'); for(const key of buff.keys()){ console.log('key is %d', key); } // key is 0 // key is 1 // key is 2 // key is 3 // key is 4 for(const value of buff.values()){ console.log('value is %d', value); } // value is 97 // value is 98 // value is 99 // value is 100 // value is 101 for(const pair of buff.entries()){ console.log('buff[%d] === %d', pair[0], pair[1]); } // buff[0] === 97 // buff[1] === 98 // buff[2] === 99 // buff[3] === 100 // buff[4] === 101
用于截取buf,并返回一个新的Buffer实例。需要注意的是,这里返回的Buffer实例,指向的仍然是buf的内存地址,所以对新Buffer实例的修改,也会影响到buf。
var buff1 = Buffer.from('abcde'); console.log(buff1); // <Buffer 61 62 63 64 65> var buff2 = buff1.slice(); console.log(buff2); // <Buffer 61 62 63 64 65> var buff3 = buff1.slice(1, 3); console.log(buff3); // <Buffer 62 63> buff3[0] = 97; // parseInt(61, 16) ==> 97 console.log(buff1); // <Buffer 62 63>
创建、拷贝、截取、转换、查找
buffer、arraybuffer、dataview、typedarray
buffer vs 编码
Buffer.from()、Buffer.alloc()、Buffer.alocUnsafe()
Buffer vs TypedArray
关于buffer内存空间的动态分配
Instances of the Buffer class are similar to arrays of integers but correspond to fixed-sized, raw memory allocations outside the V8 heap. The size of the Buffer is established when it is created and cannot be resized.
unicode对照表 https://unicode-table.com/cn/#control-character
字符编码笔记:ASCII,Unicode和UTF-8 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
更多编程相关知识,请访问:编程视频!!
위 내용은 Nodejs Buffer 모듈의 공통 API에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!