Node.js Buffer Node.js Punycode Node.js 文件系统 Node.js Buffer 稳定性: 3 - 稳定 纯Javascript语言对Unicode友好,能够很好地处理Unicode编码的字符串数据,但是难以处理二进制数据。在处理TCP流和文件系统时经常需要操作字节流。Node提供了一些机制,用于操作、创建、以及消耗字节流。 在Node.js中提供了Buffer,它可以处理二进制以及非Unicode编码的数据。 在Buffer类实例化中存储了原始数据。Buffer类似于一个整数数组,在V8堆(the V8 heap)原始存储空间给它分配了内存。一旦创建了Buffer实例,则无法改变大小。 Buffer类是全局对象,所以访问它不必使用require('buffer') 。 Buffers和Javascript字符串对象之间转换时需要一个明确的编码方法。下面是字符串的不同编码: 'ascii'- 7位的ASCII数据。这种编码方式非常快,它会移除最高位内容。 'utf8'- 多字节编码Unicode字符。大部分网页和文档使用这类编码方式。 'utf16le'- 2个或4个字节, Little Endian (LE)编码Unicode字符。编码范围(U+10000 到 U+10FFFF) 。 'ucs2'-'utf16le'的子集。 'base64' - Base64字符编码。 'binary'- 仅使用每个字符的头8位将原始的二进制信息进行编码。在需使用Buffer的情况下,应该尽量避免使用这个已经过时的编码方式。这个编码方式将会在未来某个版本中弃用。 'hex'- 每个字节都采用二进制编码。 在Buffer中创建一个数组,需要注意以下规则: Buffer是内存拷贝,而不是内存共享。 Buffer占用内存被解释为一个数组,而不是字节数组。比如,new Uint32Array(new Buffer([1,2,3,4]))创建了4个Uint32Array,它的成员为 [1,2,3,4],而不是[0x1020304]或[0x4030201]。 注意:Node.js v0.8只是简单的引用了array.buffer里的buffer,而不是对其进行克隆(cloning)。 介绍一个高效的方法,ArrayBuffer#slice()拷贝了一份切片,而Buffer#slice()新建了一份。 类: Buffer Buffer类是全局变量类型,用来直接处理二进制数据。它能够使用多种方式构建。 new Buffer(size) sizeNumber类型 分配一个新的size大小单位为8位字节的buffer。 注意:size必须小于kMaxLength,否则将会抛出RangeError异常。 new Buffer(array) arrayArray 使用一个8位字节array数组分配一个新的buffer。 new Buffer(buffer) buffer{Buffer} 拷贝参数buffer的数据到Buffer实例。 new Buffer(str[, encoding]) str String类型 - 需要编码的字符串。 encoding String类型 - 编码方式, 可选。 分配一个新的buffer ,其中包含着传入的str字符串。encoding 编码方式默认为'utf8'。 类方法: Buffer.isEncoding(encoding) encoding {String} 用来测试给定的编码字符串 如果参数编码encoding是有效的,则返回true,否则返回false。 类方法: Buffer.isBuffer(obj) obj对象 返回:Boolean obj如果是Buffer 返回true,否则返回 false。 类方法: Buffer.byteLength(string[, encoding]) string String类型 encoding String类型,可选的,默认为: 'utf8' 返回:Number类型 将会返回这个字符串真实字节长度。 encoding编码默认是:utf8。 这和String.prototype.length不一样,因为那个方法返回这个字符串中字符的数量。 例如: str = '\u00bd + \u00bc = \u00be'; console.log(str + ": " + str.length + " characters, " + Buffer.byteLength(str, 'utf8') + " bytes"); // ½ + ¼ = ¾: 9 characters, 12 bytes 类方法: Buffer.concat(list[, totalLength]) list {Array} 用来连接的数组 totalLength {Number 类型} 数组里所有对象的总buffer大小 返回一个buffer对象,它将参数buffer数组中所有buffer对象拼接在一起。 如果传入的数组没有内容,或者totalLength是0,那将返回一个长度为0的buffer。 如果数组长度为1,返回数组第一个成员。 如果数组长度大于0,将会创建一个新的Buffer实例。 如果没有提供totalLength参数,会根据buffer数组计算,这样会增加一个额外的循环计算,所以提供一个准确的totalLength参数速度更快。 类方法: Buffer.compare(buf1, buf2) buf1 {Buffer} buf2 {Buffer} 和buf1.compare(buf2)一样, 用来对数组排序: var arr = [Buffer('1234'), Buffer('0123')]; arr.sort(Buffer.compare); buf.length Number类型 返回这个buffer的bytes数。注意这未必是buffer里面内容的大小。length是buffer对象所分配的内存数,它不会随着这个buffer对象内容的改变而改变。 buf = new Buffer(1234); console.log(buf.length); buf.write("some string", 0, "ascii"); console.log(buf.length); // 1234 // 1234 length不能改变,如果改变length将会导致不可以预期的结果。如果想要改变buffer的长度,需要使用buf.slice来创建新的buffer。 buf = new Buffer(10); buf.write("abcdefghj", 0, "ascii"); console.log(buf.length); // 10 buf = buf.slice(0,5); console.log(buf.length); // 5 buf.write(string[, offset][, length][, encoding]) string String类型 - 写到buffer里 offset Number类型,可选参数,默认值: 0 length Number类型,可选参数,默认值:buffer.length - offset encoding String类型,可选参数,默认值: 'utf8' 根据参数offset偏移量和指定的encoding编码方式,将参数string数据写入buffer。offset偏移量默认值是0,encoding编码方式默认是utf8。 length长度是将要写入的字符串的bytes大小。返回number类型,表示写入了多少8位字节流。如果buffer没有足够的空间来放整个string,它将只会只写入部分字符串。length默认是 buffer.length - offset。 这个方法不会出现写入部分字符。 buf = new Buffer(256); len = buf.write('\u00bd + \u00bc = \u00be', 0); console.log(len + " bytes: " + buf.toString('utf8', 0, len)); buf.writeUIntLE(value, offset, byteLength[, noAssert]) buf.writeUIntBE(value, offset, byteLength[, noAssert]) buf.writeIntLE(value, offset, byteLength[, noAssert]) buf.writeIntBE(value, offset, byteLength[, noAssert]) value {Number 类型}准备写到buffer字节数 offset {Number 类型} 0 <= offset <= buf.length byteLength {Number 类型} 0 < byteLength <= 6 noAssert {Boolean} 默认值: false 返回: {Number 类型} 将value写入到buffer里, 它由offset和byteLength决定,支持48位计算,例如: var b = new Buffer(6); b.writeUIntBE(0x1234567890ab, 0, 6); // <Buffer 12 34 56 78 90 ab> noAssert值为true时,不再验证value和offset 的有效性。 默认是false。 **buf.readUIntLE(offset, byteLength[, noAssert]) buf.readUIntBE(offset, byteLength[, noAssert]) buf.readIntLE(offset, byteLength[, noAssert]) buf.readIntBE(offset, byteLength[, noAssert])** offset {Number 类型} 0 <= offset <= buf.length byteLength {Number 类型} 0 < byteLength <= 6 noAssert {Boolean} 默认值: false 返回: {Number 类型} 支持48位以下的数字读取。 例如: var b = new Buffer(6); b.writeUint16LE(0x90ab, 0); b.writeUInt32LE(0x12345678, 2); b.readUIntLE(0, 6).toString(16); // 指定为 6 bytes (48 bits) // 输出: '1234567890ab' noAssert 值为true时, offset不再验证是否超过buffer的长度,默认为false。 buf.toString([encoding][, start][, end]) encoding String 类型,可选参数,默认值: 'utf8' start Number 类型,可选参数,默认值: 0 end Number 类型,可选参数,默认值: buffer.length 根据encoding参数(默认是 'utf8')返回一个解码过的string类型。还会根据传入的参数start(默认是 0)和end (默认是 buffer.length)作为取值范围。 buf = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97; // 97 is ASCII a } buf.toString('ascii'); // 输出: abcdefghijklmnopqrstuvwxyz buf.toString('ascii',0,5); // 输出: abcde buf.toString('utf8',0,5); // 输出: abcde buf.toString(undefined,0,5); // encoding defaults to 'utf8', 输出 abcde 看上面buffer.write()例子。 buf.toJSON() 返回一个JSON表示的Buffer实例。JSON.stringify 将会默认调用字符串序列化这个Buffer实例。 例如: var buf = new Buffer('test'); var json = JSON.stringify(buf); console.log(json); // '{"type":"Buffer","data":[116,101,115,116]}' var copy = JSON.parse(json, function(key, value) { return value && value.type === 'Buffer' ? new Buffer(value.data) : value; }); console.log(copy); // <Buffer 74 65 73 74> buf[index] 获取或设置指定index位置的8位字节。这个值是指单个字节,所以必须在合法的范围取值,16进制的0x00到0xFF,或者0到255。 例如: 拷贝一个ASCII编码的string字符串到一个buffer,一次一个byte进行拷贝: str = "node.js"; buf = new Buffer(str.length); for (var i = 0; i < str.length ; i++) { buf[i] = str.charCodeAt(i); } console.log(buf); // node.js buf.equals(otherBuffer) otherBuffer {Buffer} 如果 this 和 otherBuffer 拥有相同的内容,返回true。 buf.compare(otherBuffer) otherBuffer {Buffer} 返回一个数字,表示 this 在 otherBuffer 之前,之后或相同。 buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) targetBuffer Buffer 对象 - Buffer to copy into targetStart Number 类型,可选参数, 默认值: 0 sourceStart Number 类型,可选参数, 默认值: 0 sourceEnd Number 类型,可选参数, 默认值: buffer.length buffer拷贝,源和目标可以相同。targetStart目标开始偏移和sourceStart源开始偏移默认都是0。sourceEnd源结束位置偏移默认是源的长度 buffer.length。 例如:创建2个Buffer,然后把buf1的16到19位内容拷贝到buf2第8位之后。 buf1 = new Buffer(26); buf2 = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf1[i] = i + 97; // 97 is ASCII a buf2[i] = 33; // ASCII ! } buf1.copy(buf2, 8, 16, 20); console.log(buf2.toString('ascii', 0, 25)); // !!!!!!!!qrst!!!!!!!!!!!!! 例如: 在同一个buffer中,从一个区域拷贝到另一个区域: 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.slice([start][, end]) start Number类型,可选参数,默认值: 0 end Number类型,可选参数,默认值: buffer.length 返回一个新的buffer,这个buffer将会和老的buffer引用相同的内存地址,根据start(默认是 0 ) 和end (默认是 buffer.length ) 偏移和裁剪了索引。 负的索引是从buffer尾部开始计算的。 修改这个新的buffer实例slice切片,也会改变原来的buffer! 例如: 创建一个ASCII字母的Buffer,进行slice切片,然后修改源Buffer上的一个byte。 var buf1 = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf1[i] = i + 97; // 97 is ASCII a } var buf2 = buf1.slice(0, 3); console.log(buf2.toString('ascii', 0, buf2.length)); buf1[0] = 33; console.log(buf2.toString('ascii', 0, buf2.length)); // abc // !bc buf.readUInt8(offset[, noAssert]) offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,读取一个有符号8位整数 整形。 若参数noAssert为true将不会验证offset偏移量参数。 如果这样offset 可能会超出buffer的末尾。默认是false。 例如: var buf = new Buffer(4); buf[0] = 0x3; buf[1] = 0x4; buf[2] = 0x23; buf[3] = 0x42; for (ii = 0; ii < buf.length; ii++) { console.log(buf.readUInt8(ii)); } // 0x3 // 0x4 // 0x23 // 0x42 buf.readUInt16LE(offset[, noAssert]) buf.readUInt16BE(offset[, noAssert]) offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从buffer对象里,根据指定的偏移量,使用特殊的endian字节序格式读取一个有符号16位整数。 若参数noAssert为true将不会验证offset偏移量参数。 这意味着offset可能会超出buffer的末尾。默认是false。 例如: var buf = new Buffer(4); buf[0] = 0x3; buf[1] = 0x4; buf[2] = 0x23; buf[3] = 0x42; console.log(buf.readUInt16BE(0)); console.log(buf.readUInt16LE(0)); console.log(buf.readUInt16BE(1)); console.log(buf.readUInt16LE(1)); console.log(buf.readUInt16BE(2)); console.log(buf.readUInt16LE(2)); // 0x0304 // 0x0403 // 0x0423 // 0x2304 // 0x2342 // 0x4223 buf.readUInt32LE(offset[, noAssert]) buf.readUInt32BE(offset[, noAssert]) offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,使用指定的endian字节序格式读取一个有符号32位整数。 若参数noAssert为true将不会验证offset偏移量参数。 这意味着offset可能会超出buffer的末尾。默认是false。 例如: var buf = new Buffer(4); buf[0] = 0x3; buf[1] = 0x4; buf[2] = 0x23; buf[3] = 0x42; console.log(buf.readUInt32BE(0)); console.log(buf.readUInt32LE(0)); // 0x03042342 // 0x42230403 buf.readInt8(offset[, noAssert]) offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,读取一个signed 8位整数。 若参数noAssert为true将不会验证offset偏移量参数。 这意味着offset可能会超出buffer的末尾。默认是false。 返回和buffer.readUInt8一样,除非buffer中包含了有作为2的补码的有符号值。 buf.readInt16LE(offset[, noAssert]) buf.readInt16BE(offset[, noAssert]) offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,使用特殊的endian格式读取一个signed 16位整数。 若参数noAssert为true将不会验证 offset 偏移量参数。 这意味着offset可能会超出buffer的末尾。默认是false。 返回和buffer.readUInt16一样,除非buffer中包含了有作为2的补码的有符号值。 **buf.readInt32LE(offset[, noAssert]) buf.readInt32BE(offset[, noAssert])** offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,使用指定的endian字节序格式读取一个signed 32位整数。 若参数noAssert为true将不会验证offset偏移量参数。 这意味着offset可能会超出buffer的末尾。默认是false。 和buffer.readUInt32一样返回,除非buffer中包含了有作为2的补码的有符号值。 **buf.readFloatLE(offset[, noAssert]) buf.readFloatBE(offset[, noAssert])** offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,使用指定的endian字节序格式读取一个32位浮点数。 若参数noAssert为true将不会验证offset偏移量参数。 这意味着offset可能会超出buffer的末尾。默认是false。 例如: var buf = new Buffer(4); buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x80; buf[3] = 0x3f; console.log(buf.readFloatLE(0)); // 0x01 **buf.readDoubleLE(offset[, noAssert]) buf.readDoubleBE(offset[, noAssert])** offset Number类型 noAssert Boolean,可选参数, 默认值: false 返回: Number类型 从这个buffer对象里,根据指定的偏移量,使用指定的endian字节序格式读取一个64位double。 若参数noAssert为true将不会验证offset偏移量参数。 这意味着offset可能会超出buffer 的末尾。默认是false。 例如: var buf = new Buffer(8); buf[0] = 0x55; buf[1] = 0x55; buf[2] = 0x55; buf[3] = 0x55; buf[4] = 0x55; buf[5] = 0x55; buf[6] = 0xd5; buf[7] = 0x3f; console.log(buf.readDoubleLE(0)); // 0。3333333333333333 buf.writeUInt8(value, offset[, noAssert]) value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量将value写入buffer。注意:value必须是一个合法的有符号 8 位整数。 若参数noAssert为true将不会验证offset 偏移量参数。 这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则不要使用。默认是false。 例如: var buf = new Buffer(4); buf.writeUInt8(0x3, 0); buf.writeUInt8(0x4, 1); buf.writeUInt8(0x23, 2); buf.writeUInt8(0x42, 3); console.log(buf); // <Buffer 03 04 23 42> **buf.writeUInt16LE(value, offset[, noAssert]) buf.writeUInt16BE(value, offset[, noAssert])** value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量和指定的endian格式将value写入buffer。注意:value必须是一个合法的有符号16位整数。 若参数noAssert为true将不会验证value和offset偏移量参数。 这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false。 例如: var buf = new Buffer(4); buf.writeUInt16BE(0xdead, 0); buf.writeUInt16BE(0xbeef, 2); console.log(buf); buf.writeUInt16LE(0xdead, 0); buf.writeUInt16LE(0xbeef, 2); console.log(buf); // <Buffer de ad be ef> // <Buffer ad de ef be> **buf.writeUInt32LE(value, offset[, noAssert]) buf.writeUInt32BE(value, offset[, noAssert])** value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量和指定的endian格式将value写入buffer。注意:value必须是一个合法的有符号32位整数。 若参数noAssert为true将不会验证value和offset偏移量参数。 这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false。 例如: var buf = new Buffer(4); buf.writeUInt32BE(0xfeedface, 0); console.log(buf); buf.writeUInt32LE(0xfeedface, 0); console.log(buf); // <Buffer fe ed fa ce> // <Buffer ce fa ed fe> buf.writeInt8(value, offset[, noAssert]) value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量将value写入buffer。注意:value必须是一个合法的signed 8位整数。 若参数noAssert为true将不会验证value和offset偏移量参数。这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false。 和buffer.writeUInt8一样工作,除非是把有2的补码的有符号整数有符号整形写入buffer。 buf.writeInt16LE(value, offset[, noAssert]) buf.writeInt16BE(value, offset[, noAssert]) value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量和指定的endian格式将value写入buffer。注意:value必须是一个合法的signed 16位整数。 若参数noAssert为true将不会验证value和offset偏移量参数。 这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false 。 和buffer.writeUInt16*一样工作,除非是把有2的补码的有符号整数 有符号整形写入buffer。 **buf.writeInt32LE(value, offset[, noAssert]) buf.writeInt32BE(value, offset[, noAssert])** value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量和指定的endian格式将value写入buffer。注意:value必须是一个合法的signed 32位整数。 若参数noAssert为true将不会验证value和offset偏移量参数。 这意味着value可能过大,或者offset可能会超出 buffer 的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false。 和buffer.writeUInt32*一样工作,除非是把有2的补码的有符号整数、有符号整形写入buffer。 **buf.writeFloatLE(value, offset[, noAssert]) buf.writeFloatBE(value, offset[, noAssert])** value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量和指定的endian格式将value写入buffer。注意:当value不是一个32位浮点数类型的值时,结果将是不确定的。 若参数noAssert为true将不会验证value和offset偏移量参数。这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false。 例如: var buf = new Buffer(4); buf.writeFloatBE(0xcafebabe, 0); console.log(buf); buf.writeFloatLE(0xcafebabe, 0); console.log(buf); // <Buffer 4f 4a fe bb> // <Buffer bb fe 4a 4f> **buf.writeDoubleLE(value, offset[, noAssert]) buf.writeDoubleBE(value, offset[, noAssert])** value Number类型 offset Number类型 noAssert Boolean,可选参数, 默认值: false 根据传入的offset偏移量和指定的endian格式将value写入buffer。注意:value必须是一个有效的64位double类型的值。 若参数noAssert为true将不会验证value和offset偏移量参数。 这意味着value可能过大,或者offset可能会超出buffer的末尾从而造成value被丢弃。 除非你对这个参数非常有把握,否则尽量不要使用。默认是false。 例如: var buf = new Buffer(8); buf.writeDoubleBE(0xdeadbeefcafebabe, 0); console.log(buf); buf.writeDoubleLE(0xdeadbeefcafebabe, 0); console.log(buf); // <Buffer 43 eb d5 b7 dd f9 5f d7> // <Buffer d7 5f f9 dd b7 d5 eb 43> buf.fill(value[, offset][, end]) value offset Number类型, Optional end Number类型, Optional 使用指定的value来填充这个buffer。如果没有指定offset (默认是 0) 并且end(默认是buffer.length) ,将会填充整个buffer。 var b = new Buffer(50); b.fill("h"); buffer.iNSPECT_MAX_BYTES Number 类型,默认值: 50 设置当调用buffer.inspect()方法后,将会返回多少bytes 。用户模块重写这个值可以。 注意这个属性是require('buffer')模块返回的。这个属性不是在全局变量Buffer中,也不在buffer的实例里。 类: SlowBuffer 返回一个不被池管理的Buffer。 大量独立分配的Buffer容易带来垃圾,为了避免这个情况,小于4KB的空间都是切割自一个较大的独立对象。这种策略既提高了性能也改善了内存使用率。V8不需要跟踪和清理过多的Persistent对象。 当开发者需要将池中一小块数据保留一段时间,比较好的办法是用SlowBuffer创建一个不被池管理的Buffer实例,并将相应数据拷贝出来,如下所示: // need to keep around a few small chunks of memory var store = []; socket。on('readable', function() { var data = socket。read(); // allocate for retained data var sb = new SlowBuffer(10); // copy the data into the new allocation data。copy(sb, 0, 0, 10); store。push(sb); }); 请谨慎使用,仅作为经常发现他们的应用中过度的内存保留时的最后手段。 Node.js Punycode Node.js 文件系统