原文地址:http://www.cnblogs.com/DeanCh...刚接触Nodejs的时候,一些概念总是让我这个前端学习者感到困惑(虽然我也是做前端的我上大学时的后端)end,世界上最好的语言,你知道的)。FileSystem、Path等功能明显的模块我可以很快看懂,但是Buffer神秘莫测的东西我一下子看不懂。因为,在前端js实践中,很少去想编码方式,字符集之类的。二元理解仅限于大学课堂。本文与其说是讨论Node的Buffer模块,不如说是从字符集和编码的角度来讨论如何理解建立Buffer模块的意义。Nodechat系列不涉及具体的API讲解,只是概述了一些我认为比较重要的特性。1.基础知识就像我们学习编程的第一课一样,我们知道计算机是一种二进制生物。它只能理解1和0,或者存在和不存在。“太极生两仪,两仪生四象,四象生八卦”。无论我们在计算中看到什么,都是通过一种特殊的编码方式,或者说约定俗成来表现出来的。我们非常熟悉的ASCII码就是这样一种规范。和摩尔斯电码一样,一个固定的值代表一个固定的含义。ASCII码用1字节8位来表示2^8=256种状态。比如大写字母A对应65,B对应66,是不是很简单?ASCII码并没有占据全部256位,只使用了128位中的一半。在一个字节中,只占用最后7位,第一位统一标识为0。但是我们不难发现,ASCII码是远远不够的,至少我们的汉字是表达不了的。后面还考虑了很多其他的解决方案,这里就不赘述了,直接说说最终的解决方案——Unicode。Unicode的想法很直接,就是想把世界上所有的字符都包括进来。我们一般认为Unicode是用两个16位的字节来表示的,完全涵盖了ASCII字符集。比如汉字“好”在unicode中的二进制表示是0101100101111101,转成十六进制就是U597D(U只是表示它们是unicode码)。前面之所以说“一般信念”,是因为这种想法是不准确的。一个Unicode平面是两个字节。我们常说的是它的基本平面,编码是U+0000到U+FFFF,常见的字符都在这个平面上。Unicode还有16个辅助平面,码位范围从U+010000到U+10FFFF。一般来说,我们只需要关注基本平面,习惯Unicode表示即可。因为,这毕竟是各种编码方式之间转换的“硬通货”。我们常说的utf-8和utf-16是什么?这些是具体的编码方式,Unicode是一个字符集。以utf-8为例,它在unicode编码的基础上重新编码,将一些不需要占用2个字节的编码转换为1个字节。比如ASCII中的那些字符,在unicode中,第一个字节全为0,很浪费空间,而且还会把汉字编码成3个字节。你可以在控制台试试Buffer.from('me','utf8')看看编码后的字节数。javascript使用哪种编码?JavaScript使用Unicode字符集,但只支持一种编码方式。那就是USC-2。你没听说过吗?你可以理解为utf-16。但它与UTF-16到底有什么关系呢?两者的关系简单来说就是UTF-16代替了UCS-2,或者UCS-2融入了UTF-16。所以,现在只有UTF-16,没有UCS-2。UCS-2只支持两个字节,而在它之后出现的UTF-16在UCS-2的基础上使用辅助平面可以支持4个字节。由于UCS-2被集成到UTF-16中,所以UTF-16中有一些字符,但UCS-2不存在。遇到这种情况怎么办?您可以参考以下参考资料中阮老师的讲述。2.Buffer生成相关的重要APIBuffer.alloc(size[,fill[,encoding]])Buffer.allocUnsafe(size)Buffer.allocUnsafeSlow(size)Buffer.from(array)buf.fill(value[,offset[,end]][,encoding])在Buffer生成的过程中,最关心的就是内存的申请和分配。原先用newBuffer()生成Buffer的方法不建议再次使用。与Buffer.allocUnsafe()方法一样,它可能包含敏感数据。为什么它会包含敏感数据?在生成buffer的过程中,并不是一步完成的,而是分为两步,1.申请内存空间,2.填充请求的内存空间。Buffer.allocUnsafe()方法只完成了第一步。没有完成第二步的后果就是申请的空间可能会“残留”在之前内存上的数据。毕竟一块内存在电脑中总是申请然后释放的,难免有些数据没有及时清理。当然,由于少了第二步,速度自然要快很多。consta=Buffer.allocUnsafe(10);console.log(a)//
