Buffer

    前面提及到一些关于buffer类的问题,当时不是很明确 那么就次机会顺便深入探讨一下这个东西到底干嘛的出现在什么时候,如何使用.昨天跟朋友聊天他说我每一篇博文内容太长太长了 虽然很精细,但是的确深入的有点多了,so 这篇开始尽量多分几篇共同讨论,减少单一文章内容过多的问题哈.  想起个事儿来这,这两篇博文其实都是在深挖原生模块fs,原生如果操作文件的,细心的孩砸都会发现的,对于fs模块学习还有两章,我准备这两张完事儿之后开始学习http模块 目前项目中有用到部分http模块的功能,好了不废话了继续往下看.

上篇文章围绕数据文件操作探讨了一下node里面如何操作文件的,但是javascript中只有字符串类型,并不支持二进制(文件操作都是二进制类型的,这也就解决了读取文件时候为啥不区分文件类别的问题,因为不管啥文件txt,php等等内容都会当做二进制数据取处理,个人理解啊并不代表官方解释),抢到的node工程师们肯定不能容忍这么low的问题,因此buffer诞生了,buffer说是一个类,更准确的说是一个缓存区域!它在内存中的作用就是单独存放二进制说的区域.在nodejs中buffer是随着node一同发布的核心库,他是存在于V8堆内存之外的一块原始内存中.而这个内存大小在官方文档中也有说明:

目前,V8引擎有一个默认的32位系统512MB内存的限制,在64位系统1.4gb。极限可提高设置- max_old_space_size到最大~ 1024(~ 1 GB)(32位)和4096(~ ~ 4GB)(64位),但建议你把你的单过程分成几个工人如果你命中内存限制。

但是Buffer是如果回收的如何设定有效时间期限的真的很难找到相关文章,不过确实会被GC回收,相关文章我就不再这里贴出来了关于这方面的文章真的太少了..似乎没人去挖这个还是不值得去挖呢?

buffer类的创建类似于创建数组 :

var b=new buffer(10); //创建一个10字节的实例

var b=new buffer([1,2,3])//当然里面也可以是数组

var b=new buffer("嘿嘿嘿","utf-8")//这个也可以有 而且还设定了编码方式

buffer.write

buf.write(string,[offset],[length],[encoding]),写入buffer的参数,string 需要写入的字符串,offset 缓存区开始的索引值,length 写入长度(当然如果缓存区满了就只能写入部分啦),encoding 编码方式 默认UTF-8

一个小李子:

buf = new Buffer(256);
len = buf.write("www.w3cschool.cn"); console.log("写入字节数 : "+ len);

  这个缓存方式有点点像redis,但是它并没有有效期啊什么什么的,而且格式也是大相径庭,给我的感觉这个写入缓存区的就是一个txt文本...啥都是一行里面一直写下去但是如何找到指定的内容呢?

bufffer.toString

是不是感觉很low比...别忘了 人家也是有参数的buffer.toString(encoding,start,end),你写在什么位置了直接取呗来来上例子看一下瞬间明白了:

buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97;
} console.log( buf.toString('ascii')); // 输出: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5)); // 输出: abcde
console.log( buf.toString('utf8',0,5)); // 输出: abcde
console.log( buf.toString(undefined,0,5)); // 使用 'utf8' 编码, 并输出: abcde

  好了额,还有很多灰常灰常简单的方法,例如: 比较compare,合并concat,复制copy,剪切slice 我就不一一介绍了,看看文档简直不要再简单了...http://www.w3cschool.cn/nodejs/x1u41ith.html

这里我要说一下它的很多很多转换方法,前面也说到了实际上buffer缓存区域是有大小的而且是有回收机制的(虽然不清楚)大小肯定是有限制的能省点就省点先介绍一下转换方法:

阅读Buffer的API文档时,我们会发现更多的是readXXX()writeXXX()开头的API,具体如下:

  • buf.readUIntLE(offset, byteLength[, noAssert])
  • buf.readUIntBE(offset, byteLength[, noAssert])
  • buf.readIntLE(offset, byteLength[, noAssert])
  • buf.readIntBE(offset, byteLength[, noAssert])
  • buf.readUInt8(offset[, noAssert])
  • buf.readUInt16LE(offset[, noAssert])
  • buf.readUInt16BE(offset[, noAssert])
  • buf.readUInt32LE(offset[, noAssert])
  • buf.readUInt32BE(offset[, noAssert])
  • buf.readInt8(offset[, noAssert])
  • buf.readInt16LE(offset[, noAssert])
  • buf.readInt16BE(offset[, noAssert])
  • buf.readInt32LE(offset[, noAssert])
  • buf.readInt32BE(offset[, noAssert])
  • buf.readFloatLE(offset[, noAssert])
  • buf.readFloatBE(offset[, noAssert])
  • buf.readDoubleLE(offset[, noAssert])
  • buf.readDoubleBE(offset[, noAssert])
  • buf.write(string[, offset][, length][, encoding])
  • buf.writeUIntLE(value, offset, byteLength[, noAssert])
  • buf.writeUIntBE(value, offset, byteLength[, noAssert])
  • buf.writeIntLE(value, offset, byteLength[, noAssert])
  • buf.writeIntBE(value, offset, byteLength[, noAssert])
  • buf.writeUInt8(value, offset[, noAssert])
  • buf.writeUInt16LE(value, offset[, noAssert])
  • buf.writeUInt16BE(value, offset[, noAssert])
  • buf.writeUInt32LE(value, offset[, noAssert])
  • buf.writeUInt32BE(value, offset[, noAssert])
  • buf.writeInt8(value, offset[, noAssert])
  • buf.writeInt16LE(value, offset[, noAssert])
  • buf.writeInt16BE(value, offset[, noAssert])
  • buf.writeInt32LE(value, offset[, noAssert])
  • buf.writeInt32BE(value, offset[, noAssert])
  • buf.writeFloatLE(value, offset[, noAssert])
  • buf.writeFloatBE(value, offset[, noAssert])
  • buf.writeDoubleLE(value, offset[, noAssert])
  • buf.writeDoubleBE(value, offset[, noAssert])

这些API为在Node.js中操作数据提供了极大的便利。假设我们要将一个整形数值存储到文件中,比如当前时间戳为1447656645380,如果将其当作一个字符串存储时,需要占用11字节的空间,而将其转换为二进制存储时仅需6字节空间即可:

var buf = new Buffer(6);

buf.writeUIntBE(1447656645380, 0, 6);
// <Buffer 01 51 0f 0f 63 04> buf.readUIntBE(0, 6);
// 1447656645380

  这段来自另外一位大神一年前的博客了并且根据取出数据结构被混乱特意写了一个模块去解决这个问题lei-proto 有时间膜拜一下,传送门-->http://cnodejs.org/topic/56499568d28aa64101600fdc

编码转换

   这里主要是介绍一下中文转换我接触的两个第三方库,很多人都在用与其一直用新东西探索未知区域我更愿意相信旧的,毕竟千万人都使用过..不废话了

前面经常用到toString()这个方法而node本身对中文以及其他多字节编码支持并不好,需要第三方库来协调一下,这里主要介绍一下常用的iconv-lite和encoding

 iconv-lite

     首先先来了解一下iconv, iconv-lite,encoding:

iconv:是在类Unix系统中一种标准字符集转换接口,用于在不同字符集编码之间进行转换,最早出现在HP-UX系统中,阐释了node-iconv的起源.

     iconv-lite:是iconv的纯js实现,支持的编码包括node.js原生编码:utf8, ucs2, ascii, binary, base64;同时支持广泛使用的单字节编码:Windows 125x family, ISO-8859 family, IBM/DOS codepages, Macintosh family, KOI8 family, latin1, us-ascii;多字节编码:gbk, gb2313, Big5, cp950。官方宣称比node-iconv更快。
 
     encoding:是对node-iconv和iconv-lite的再次封装,encoding首先调用node-iconv,如果node-iconv无法解析,则调用iconv-lite作为替代方案.相当于iconv-lite的包装版.
     
     这两个第三方库 安装都一样sup简单 npm install iconv-lite  或者 npm install encoding
     
     使用方法我考了别人两段代码基本上看看就知道了没啥特殊的,都是替代了原有的toString()方法,encoding稍微说一下,先是iconv-lite

var iconv = require('iconv-lite');

// Convert from an encoded buffer to js string.
str = iconv.decode(buf, 'win1251'); // Convert from js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251'); // Check if encoding is supported
iconv.encodingExists("us-ascii")

  encoding 需要绕个小丸子,encoding模块就一个方法convert(),使用方法为:encoding.convert(text, toCharset, fromCharset)。

             text: 需要转换的对象,可以为Buffer或者String对象。
             toCharset: 转换后的编码。

             fromCharset: 转换前的编码,缺省为uft8。
            转换后的输入结果为Buffer对象

var encoding = require('encoding');

var result = encoding.convert("ÕÄÖÜ", "Latin_1");
console.log(result); //<Buffer d5 c4 d6 dc>

  

深入基础(四)Buffer,转码的更多相关文章

  1. Spring基础系列-AOP源码分析

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9560803.html 一.概述 Spring的两大特性:IOC和AOP. AOP是面向切 ...

  2. Python全栈开发【基础四】

    Python全栈开发[基础四] 本节内容: 匿名函数(lambda) 函数式编程(map,filter,reduce) 文件处理 迭代器 三元表达式 列表解析与生成器表达式 生成器 匿名函数 lamb ...

  3. Bootstrap<基础四> 代码

    Bootstrap 允许您以两种方式显示代码: 第一种是 <code> 标签.如果您想要内联显示代码,那么您应该使用 <code> 标签. 第二种是 <pre> 标 ...

  4. 36 网络相关函数(四)——live555源码阅读(四)网络

    36 网络相关函数(四)——live555源码阅读(四)网络 36 网络相关函数(四)——live555源码阅读(四)网络 简介 7)createSocket创建socket方法 8)closeSoc ...

  5. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  6. Springboot与Thymeleaf模板引擎整合基础教程(附源码)

    前言 由于在开发My Blog项目时使用了大量的技术整合,针对于部分框架的使用和整合的流程没有做详细的介绍和记录,导致有些朋友用起来有些吃力,因此打算在接下来的时间里做一些基础整合的介绍,当然,可能也 ...

  7. List-LinkedList、set集合基础增强底层源码分析

    List-LinkedList 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 继上一章继续讲解,上章内容: List-ArreyLlist集合基础增强底层源码分析:https:// ...

  8. List-ArrayList集合基础增强底层源码分析

    List集合基础增强底层源码分析 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] 集合分为三个系列,分别为:List.set.map List系列 特点:元素有序可重复 有序指的是元素的 ...

  9. C#_02.13_基础四_.NET方法

    C#_02.13_基础四_.NET方法 一.方法概述: 方法是一块具有名称的代码.可以通过方法进行调用而在别的地方执行,也可以把数据传入方法并接受数据输出. 二.方法的结构: 方法头  AND  方法 ...

随机推荐

  1. CSS3 @font-face 规则

    指定名为"myFirstFont"的字体,并指定在哪里可以找到它的URL: @font-face { font-family: myFirstFont; src: url('San ...

  2. 【转载】C#中可使用string.Empty代表空字符

    在C#中,如果赋值一个字符串为空白字符串,我们一般会用“”的形式对字符串进行赋值操作,其实在C#的字符串类String类中,有个专门的常量string.Empty来代表空字符串,可直接在赋值的时候使用 ...

  3. ColdFusion 编写WebService 示例

    1.开发 Web Services,编写cfcdemo.cfc组件,代码如下: <cfcomponent style ="document" namespace = &quo ...

  4. django路由系统及分发路由的本质

    路由系统 当我们启动一个django项目后,想要通过浏览器访问到django项目中的资源 就需要在django中的urls项目中进行路由配置 urlpatterns = [ url(r'^admin/ ...

  5. React Native 开发豆瓣评分(五)屏幕适配方案

    前言 React Native 是以实际像素 dp 为单位的,这导致在不同分辨率的屏幕会有不一样的显示情况. 在原生 Android 中,可以根据不同的分辨率添加不同的样式目录,以解决不同分辨率的问题 ...

  6. angular 8 配置路由

    一.生成路由文件 按照惯例,有一个独立模块来配置相关路由,这个模块类的名字叫做AppRoutingModule,位于src/app下的app-routing.module.ts文件中. 使用CLI生成 ...

  7. vue页面跳转

    一.在template中的常见写法: <router-link to="/recommend"> <button class="button" ...

  8. python的continue和break

    continue:表示终止当前循环,开始下一次循环 break:终止所有循环 s = 0 while s < 3: s += 1 print(s) continue#'@' print(abc) ...

  9. net 与或非

    && op1 && op2 当op1和op2都是true时,返回true :如果op1的值是false,则不运算右边的操作数 || op1 || op2 当op1和op ...

  10. Javascript诞生记 [转载]

    1. "1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览,不具备与访问者互动 ...