熟悉JavaScript的童鞋应该对Node.js都不陌生,没错Node.js是一个基于Chrome JavaScript运行时建立的平台,用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。

正是由于Node.js的这些特性使得其在如今的编程中越来越受欢迎,对于新手程序猿来说很有必要掌握Node.js技术。本文小编就将为大家介绍Node.js中Buffer类的使用,希望对大家学习Node.js有帮助吧。

其实,Buffer类在Node.js的使用中,经常会用到,特别是在用Node.js做服务端开发时,http、tcp、udp、文件io等等类型的操作,都离不开Buffer类。

Buffer是什么

Buffer代表一个缓冲区,存储二进制数据,是字节流,在网络传输时,就传输的这种字节流。

编码格式

虽然一般的字符串是有编码格式的,比如UTF-8。但Buffer是没有编码格式的。两者可以相互转换,转换时必须指定编码格式。

在http模块中,http.createServer方法需要的回调函数的原型是:

function (req, res)

这个回调的第一个参数,req,类型是http.IncomingMessage,而http.IncomingMessage是一个只读的流,实现了Readable接口,stream.Readable读到的数据(监听data事件可以处理),就是Buffer对象,是字节流。而我们在程序中使用时,经常是要转换为String。反过来,res(类型http.ServerResponse,可写的流,实现了Writable接口)有个方法setDefaultEncoding,用来设置流的编码格式,在write数据时,会使用指定的编码格式来编码数据,然后发送给客户端。

这就是说,网络传输的是Buffer,程序需要处理String,Buffer和String之间可以转换。Buffer有toString方法,可以按指定的编码格式将字节流转换为String。

在文件系统模块中,fs.createWriteStream和fs.createReadStream两个方法都有一个可选参数options,可以指定defaultEncoding,这里指定的编码格式,也是用于在Buffer和String之间转换的。

目前我们在Node.js里,Buffer在转换为字符串时,toString方法的第一个参数就是编码类型,支持常见的编码格式:

utf8,多字节编码的Unicode字符,大多数文档和网页采用这种编码格式

ascii,8bit编码,一个字符占1个字节

utf16le,小端编码的unicode字符

utf16be,大端编码的unicode

ucs2,unicode编码,每个字符占两个字节

base64,Base-64字符串编码

hex,每个字节编码为两个十六进制字符

假如你不确认某个编码格式是否正确,可以使用Buffer.isEncoding(encoding)方法来测试。

在使用Buffer的toString方法时,如果你不指定编码格式,则默认使用utf8来转换。toString原型:

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

第一个参数是编码格式,第二个是开始位置(0到buf.length-1),第三个是结束位置(不包含这个索引位置的数据)。

创建一个Buffer实例

对于Buffer实例的创建,使用new操作符,有四种方法可实现:

new Buffer(size),创建一个指buffer定大小的buffer

new Buffer(array),根据一个字节数组来创建一个buffer

new Buffer(str[,encoding]),根据一个字符串和编码格式创建buffer,不指定编码时默认使用utf8

new Buffer(buffer),根据buffer实例创建一个新的buffer

比如下面的代码可以创建Buffer的实例:

var buf1 = new Buffer(256);

var buf2 = new Buffer("Hello Buffer");

var buf3 = new Buffer([0x65,0x66,0x67]);

var buf4 = new Buffer(buf2);

但有一点需要说明的是,使用new Buffer(size)分配的缓冲区,是未初始化的。那块内存里,可能什么都有。试试下面的代码:

var buf1 = new Buffer(256);

buf1.write('abc');

console.log("buf1\'s content: ", buf1.toString());

上面的代码企图使用toString转换Buffer,可是你会看到控制台输出了很多乱码……修改一下,使用buf.fill()方法填充一下就好了:

var buf1 = new Buffer(256);

buf1.fill(0);

buf1.write('abc');

console.log("buf1\'s content: ", buf1.toString());

字符串是“\0”结尾的,调用了buf1.fill(0)之后,就一切安好。

往缓冲区写数据

前面我们已经使用了buf.write方法来向缓冲区里写入数据了。write的原型如下:

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

buf.write用来向缓冲区中写入一个字符串,返回实际写入的字节数。参数含义如下:

string,待写入的字符串对象

offset,缓冲区偏移量,指定的话就从这个位置开始写入,不指定就默认为0

length,要写入的字节数

encoding,代谢如字符串的编码格式,默认为utf8

Buffer还有很多其他的方法,让你操作缓冲区。比如writeUInt8、writeUInt16LE、writeUInt16BE、writeUInt31LE、writeUInt32BE、writeInt8、writeInt16LE、writeInt32LE等等。

LE - little endian,小端字节序。

BE - big endian,大端字节序,即网络字节序。

需要说明的是,writeX方法,不像文件一样自动为你保存当前位置,你不指定offset,它就总是从0位置开始写。

从缓冲区读数据

buf.toString其实是一种读数据的方式。当然,还有其它的,比如buf[index]可以根据下标读取字节,buf.readIntXXX,buf.readUIntXXX……

buf.toJSON()可以把一个Buffer对象转换为JSON格式。当你针对一个Buffer对象调用JSON.stringify方法时,buf.toJSON()就会被调用。比如:

var buf = new Buffer('test');

var json = JSON.stringify(buf);

console.log(json);

// '{"type":"Buffer","data":[116,101,115,116]}'

缓冲区的长度

一个Buffer对象的大小,在创建时就固定下来,创建之后不可改变。如果你觉得Buffer里保存的是字符串时,不妨可以试试下面的代码有助于理解这一点:

var buf1 = new Buffer(256);

buf1.fill(0);

buf1.write('abc');

console.log("buf1\'s length - %d, not 3\n", buf1.length);

buf1.write('abcdef');

console.log("buf1\'s length - %d, not 6\n", buf1.length);

另外当你要从确定字符串在缓冲区中占用的字节长度时,不能使用字符串的length属性,因为String.length返回的是字符长度。而对于采用UTF8等编码格式编码的字符串,一个字符可能占用多个字节。所以,String.length所代表的字符串长度和字节长度就不一致。注意,Buffer.length返回的是缓冲区的字节长度,而且是创建时的那个长度,不会随着缓冲内容变化而变化。

如果要想衡量一个字符串占用的字节长度,可以使用Buffer.byteLength(string[,encoding])这个方法,它会测量一个字符串在指定编码格式下占用的字节长度。具体的,可以看看下面这个例子:

var name = new String('who is \u5F20\u4E09\u4E30?');

console.log('name.length = %d', name.length);

console.log('byteLength = %d', Buffer.byteLength(name, 'utf8'));

缓冲区操作

Buffer还支持切片、拷贝、拼接、比较等操作。

buf.slice([start[, end]])可以根据起止位置(不包含结束位置对应的数据)对一个缓冲区进行切片,返回一个新的Buffer对象,方便我们操作缓冲区的某个区域。但值得注意的是,这个切片是对原有缓冲区的引用,而不是副本,你对切片内容的修改,实际上修改的是原始的缓冲区。这个方法返回一个代表切片的Buffer对象。

buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])可以将一个缓冲区指定区域的内容拷贝到另一个缓冲的指定区域。类似C语言里的memcpy。targetStart指定目标缓冲区的起始偏移,sourceStart指定源缓冲区的起始偏移,它们默认都是0;sourceEnd指定源缓冲区的结束位置,默认是源缓冲区的长度。实际复制时,会比较目标缓冲区的长度和待复制区域的长度,哪个小按哪个来,不会越界。

Buffer有一个类方法,concat(list[,totalLength]),可以将一串缓冲区拼接成一个。第一个参数list是一个缓冲区数组,第二是待拼接的缓冲区的总长度。如果你不提供totalLength,concat会自己遍历list中的缓冲区计算总长度,会有一点性能损失。这个方法返回拼接后的缓冲区。

看个示例代码,演示切片、拷贝和拼接的用法:

var buf1 = new Buffer('1234');

var buf2 = new Buffer('12567');

var bufList = [buf1, buf2];

var buf3 = Buffer.concat(bufList);

console.log('buf3 - %s', buf3.toString());

var buf4 = buf3.slice(3, 8);

console.log('buf4 - %s', buf4.toString());

var buf5 = new Buffer(5);

buf3.copy(buf5, 0, 1);

console.log('buf5 - %s', buf5.toString());

buf.equals(otherBuffer)判断当前缓冲区是否和另一个相等,相等时返回true。

buf.compare(otherBuffer)比较当前缓冲区和另一个缓冲区的大小,相等返回0,小于返回-1,大于返回1。看下面的示例代码:

var buf1 = new Buffer('1234');

var buf2 = new Buffer('12567');

var buf3 = new Buffer('1234');

var buf4 = new Buffer('0123');

console.log('buf1.compare(buf2) = ', buf1.compare(buf2));

console.log('buf1.compare(buf3) = ', buf1.compare(buf3));

console.log('buf1.compare(buf4) = ', buf1.compare(buf4));

以上就是Node.js中Buffer类的一些相关用法,大家在学习Node.js时,可尝试开发一个小项目将上面这些方法都动手使用、实践一遍,加深印象,以便今后开发中,遇到类似功能信手捏来。

node MySQL buffer_node.js中buffer方法使用说明相关推荐

  1. node mysql await_node.js中对 mysql 进行增删改查等操作和async,await处理

    要对mysql进行操作,我们需要安装一个mysql的库. 一.安装mysql库 npm install mysql --save 二.对mysql进行简单查询操作 const mysql = requ ...

  2. python分配buffer_Node.js中的buffer如何和python中的buffer相对应

    我的整个需求可以分解为下面几步: step1.Node.js发送Buffer类型数据: 因为Node.js中fs文件系统读取文件后的回掉中均返回的为Buffer类型的数据, 直接通过queryStri ...

  3. JS中toFixed()方法的问题及解决方案

    JS中toFixed()方法的问题及解决方案 参考文章: (1)JS中toFixed()方法的问题及解决方案 (2)https://www.cnblogs.com/gushen/archive/201 ...

  4. js中toFixed方法的两个坑

    js中toFixed方法的两个坑 toFixed返回结果是string,后续使用它计算会错误 toFixed返回结果可能出现负零-0.00 toFixed返回结果是string,后续使用它计算会错误 ...

  5. Js中fetch方法

    Js中fetch方法 fetch()方法定义在Window对象以及WorkerGlobalScope对象上,用于发起获取资源的请求,其返回一个Promise对象,这个Promise对象会在请求响应后被 ...

  6. created写法_vue.js中created方法作用

    这是它的一个生命周期钩子函数,就是一个vue实例被生成后调用这个函数.一个vue实例被生成后还要绑定到某个html元素上,之后还要进行编译,然后再插入到document中.每一个阶段都会有一个钩子函数 ...

  7. 【转载】JS中bind方法与函数柯里化

    原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...

  8. 前端开发:JS中join()方法的使用总结

    前言 在前端开发过程中,对数组的数据进行处理也是比较常见的操作之一,而且对数组进行操作的频率远远大于对 对象进行操作,因此在开发过程中对于数组里面的数据进行处理是一项比较重要的技能,尤其是对于刚入行的 ...

  9. vue在created调用点击方法_vue.js中created方法的使用详解

    这次给大家带来vue.js中created方法的使用详解,使用vue.js中created方法的注意事项有哪些,下面就是实战案例,一起来看一下. 这是它的一个生命周期钩子函数,就是一个vue实例被生成 ...

最新文章

  1. 第六章 模型的验证、监控与调优
  2. 修改 堆栈大小 普适性方案总结 (跨平台 windows linux 栈设置大小)
  3. MyBatis的高级映射之多对一
  4. ShopEx customSchema 定制可以根据客户的需求对网站进行相应功能的添加修改或者删除
  5. 数据结构实验二 树和二叉树的实现
  6. Maven中maven-source-plugin,maven-javadoc-plugin插件的使用:
  7. “大胃王”吃播注意了 国家明确禁止发布量大多吃、暴饮暴食等节目
  8. html未填写提示,文本框输入信息,未输入的文本框会提示输入,并且未输入的文本框会变红...
  9. 20款绝佳的HTML5应用程序示例
  10. navicat for mysql提示_Navicat for MySQL使用教程: MYSQL的提示操作和技巧
  11. 小明刚刚看完电影《第39级台阶》离开电影院的时候,他数了一下礼堂前的台阶,刚好是39级 站在台阶前,他突然又想到了一个问题 如果我每步只能迈上一个或者两个台阶,先迈左脚,然后左右交替,也就是说一共
  12. CSS中常见中文字体的英文名称
  13. Docker微服务-镜像构建交付和使用rancher进行容器创建管理
  14. 大天使之剑H5游戏超详细图文架设教程
  15. 《Real-Time Rendering 4th Edition》读书笔记--简单粗糙翻译 第六章 纹理 Texturing
  16. 计算机手速如何学,拼不过手速的你,来学学这些操作
  17. PL-SLAM 配置和测试
  18. 高校挑选校园智能门锁指南,学校后勤管理者速看
  19. Go C画图 CSP-J CSP-S NOIP 信息学奥赛 2023.01.30 测试题
  20. VUE之Vxe-table动态生成多级表头

热门文章

  1. python爬取主播信息
  2. C#的常见算法(面试)(转)
  3. bootstrap30-辅助类展示不同的背景颜色
  4. 导出Excle java
  5. Java文件路径(getResource)
  6. 轻松自动化---selenium-webdriver(python) (七)
  7. 关于C++中的条件编译
  8. 在路由器使用ACL防止IP地址欺骗
  9. Blocks与Dispatch Queue的使用
  10. Kinect+OpenNI学习笔记之4(OpenNI获取的图像结合OpenCV显示)