标签:
本文为阅读朴灵大大的《深入浅出node.js》笔记:
在前端开发的时候,我们不曾用过buffer,也没得用。buffer是node环境引入的,用来方便应对二进制数据的处理。这里我们对它应该有基础的理解和正确的定位,方能更好的使用它。
1、buffer不属于v8包含的内容
buffer是node通过c++实现的,跟其他的一些核心模块类似,并不是说修改v8使,在v8中实现这个功能。
2、buffer不需要require
我们在使用例如文件模块等等的模块都需要require来引入对应的模块,但buffer不需要,主要原因是因为它太常见了,所以在加载的时候,系统默认就把buffer加载到global上的Buffer上了,所以无需require就可以直接使用它。
3、buffer中用来存储数据的内存不属于v8,不受v8内存限制影响
buffer占用内存分两部分,一部分是buffer对象,一部分的用来存储数据的pool。new出来的buffer对象是属于v8内存的一个对象,与v8的其它变量一样都满足自动垃圾回收的机制。而用来存储数据的pool是由c++直接向系统申请内存来存储的,有自己的内存处理机制。所以buffer数据存储的内存是数据v8之外,不会受到v8的最大内存限制的问题影响。对应的buffer对象会存放pool所在的位置信息和大小信息。
4、buffer和字符串可以很方便的互相转换,但是他们是不同的
a)buffer也有length,但buffer的长度主要跟数据具体存储的字节数相关,而字符串却跟对应编码有关。
b)因为buffer实际上跟对应编码是没有直接关系,所以,你甚至可以在一个buffer里面存储多种编码的内容,只要你能按存放的位置取出对应的内容即可。
c)平常的数据流操作的时候,使用的其实都是buffer,方便数据的二进制传输,而字符串主要是引擎中字符串操作时使用的。
buffer常见处理技巧:
1、我们经常在读取一个数据流的情况下用chunks+=chunk的形式来把数据流data事件返回的信息拼接在一起:
var rs=createReadStream(); var chunks=‘‘; rs.on(‘data‘,function(chunk){ chunks+=chunk; }); rs.on(‘end‘,function(){ console.log(chunks); });
这里主要的问题在于,data事件传入的chunk实际上是一个buffer数据,他的内容可能是截断的,并不是一个完整的字符串,而后面使用了
chunks+=chunk,实际上是把buffer转为字符串再拼接。这里如果是被截断的buffer就可能导致无法正常识别为字符串,展示为乱码。
所以这里应该使用buffer直接拼接为完成的buffer的形式来解决。
var rs=createReadStream(); var chunks=[]; rs.on(‘data‘,function(chunk){ chunks.push(chunk); }); rs.on(‘end‘,function(){ console.log(Buffer.concat(chunks)); });
2、我们可能会有一个很长的字符串,需要在每次用户请求时返回给用户,如:
var longStr=‘‘; for(var i=0;i<10*1024;i++){ longStr+=‘a‘; } //longStr=new Buffer(longStr); http.createServer(function(req,res){ res.writeHead(200); res.end(longStr); });
这种情况下的问题就在于,每次请求调用res.end的时候,都是需要做一次操作等价longStr=new Buffer(longStr);比较浪费cpu,
所以这里应该把这一步的动作提前。把代码中的注释去掉,这样,我们就会把原来的longStr直接存储为Buffer,后续都可以直接使用,不浪费cpu。
本文为阅读朴灵大大《深入浅出node.js》的读书笔记
标签:
原文地址:http://www.cnblogs.com/chianquan/p/5700532.html