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. 有助于改善性能的Java代码技巧

    前言 程序的性能受到代码质量的直接影响.这次主要介绍一些代码编写的小技巧和惯例.虽然看起来有些是微不足道的编程技巧,却可能为系统性能带来成倍的提升,因此还是值得关注的. 慎用异常 在Java开发中,经 ...

  2. 使用jQuery开发tab选项卡插件

    为了复习巩固jQuery的插件开发.HTML和CSS方面的知识,做了一个简单的tab选项卡插件,简单记录一下开发.使用的过程,以备日后使用. 一.插件效果 tab选项卡插件常用的功能均已实现,包括:动 ...

  3. D1-JavaScript

    下面的代码,我想要打印出hey jack,结果却打印出hey rose,为什么? function greet(person) { if (person == {name: 'jack'}) { co ...

  4. unity 编译之后签名被改变

    原因:在gradle 模式下编译,把development build 勾上 会使签名改变

  5. Android笔记(六十一)动态添加组件

    想要一个功能,点击按钮,可以在已有的布局上,新添加一组组件. 动态的创建组件,本质上还是创建组件,只不过是在程序中根据逻辑来创建.大致步骤是找到要创建控件的位置,然后将要创建的组件添加进去. 看代码: ...

  6. c# 常见文件操作

  7. 使用jib上传docker镜像

    Jib 无需Docker守护程序即可为Java应用程序构建优化的Docker和OCI映像-无需深入了解Docker最佳实践.它可以作为Maven和Gradle的插件以及Java库使用. 我使用的是Ma ...

  8. 使用AutoIt实现文件上传

    在网页上上传文件的时候,Selenium无法直接操作如Flash.JavaScript 或Ajax 等技术所实现的上传功能,这时候我们需要借用一个叫做AutoIt的软件来帮助我们事先自动化的上传操作. ...

  9. 0029redis单机版环境搭建

    linux环境下安装单机版redis,主要分为如下几步: 1. 安装gcc 2.下载安装包 3.解压安装包 4.进入解压目录并执行make和make install命令 5.查看默认安装目录 6.更改 ...

  10. PHP——汉字完美转为ASCII码

    前言 对接联通的接口,让我学会了不少PHP偏门函数....,主要对方用的py,我这用的PHP,人家一个函数解决了, 我这还要自己写方法,也是比较蛋疼,但是学到东西还是很开心的~ 代码 字符串转为ASC ...