zoukankan      html  css  js  c++  java
  • NodeJS 难点(网络,文件)的 核心 stream 一:Buffer

    stream应用一图片转存服务

    stream github教程

    文件操作和网络都依赖了一个很重要的对象—— Stream, 而这个 <node深入浅出> 没有分析的,  

    所以读完这本书, 在实践中还会遇到很多困难

    stream 是处理 buffer

    JavaScript 没有读取或者操作二进制数据流的机制。

    Buffer 类作为 NodeJS API 的一部分被引入,以便能够和 TCP 等网络流和文件流等进行交互。

    总而言之,Buffer 类是用来处理二进制数据,

    因为太常用了,所以直接放在了全局变量里,使用的时候无需 require。

    Buffer 类的实例类似于整型数组,不过缓冲区的大小在创建时确定,不能调整。

    Buffer 对象不同之处在于它不经 V8 的内存分配机制,Buffer 是一个 JavaScript 和 C++ 结合的模块,内存由 C++ 申请,JavaScript 分配。

    实例化 Buffer

    在 NodeJS v6 之前都是通过调用构造函数的方式实例化 Buffer,根据参数返回不同结果。处于安全性原因,这种方式在 v6 后的版本中已经被废除,提供了

    • Buffer.from()
    • Buffer.alloc()
    • Buffer.allocUnsafe()

    三个单独的,职责清晰的函数处理实例化 Buffer 的工作。

    • Buffer.from(array):返回一个内容包含所提供的字节副本的 Buffer,数组中每一项是一个表示八位字节的数字,所以值必须在 0 ~ 255 之间,否则会取模
    • Buffer.from(arrayBuffer):返回一个与给定的 ArrayBuffer 共享内存的新 Buffer
    • Buffer.from(buffer):返回给定 Buffer 的一个副本 Buffer
    • Buffer.from(string [, encoding]):返回一个包含给定字符串的 Buffer
    • Buffer.alloc(size [, fill [, encoding]]):返回指定大小并且“已填充”的 Buffer
    • Buffer.allocUnsafe(size):返回指定大小的 Buffer,内容必须用 buf.fill(0) 等方法填充, 一般不实用
    // 0x 表示 16 进制
    
    Buffer.from([1, 2, 3]) // [0x1, 0x2, 0x3]
    
    Buffer.from('test', 'utf-8') // [0x74, 0x65, 0x73, 0x74]
    
    Buffer.alloc(5, 1) // [0x1, 0x1, 0x1, 0x1, 0x1] Buffer.allocUnsafe(5); // 值不确定,后面详谈

    呵呵, 基本看不懂

    Buffer.allocUnsafe() 的执行会快于 Buffer.alloc() 看名字很不安全,确实也不安全。

    当调用 Buffer.allocUnsafe() 时分配的内存段尚未初始化(不归零),这样分配内存速度很块,但分配到的内存片段可能包含旧数据。

    如果在使用的时候不覆盖这些旧数据就可能造成内存泄露,虽然速度快,尽量避免使用。

    编码

    Buffer 支持以下几种编码格式

    • ascii
    • utf8
    • utf16le
    • base64
    • binary
    • hex

    Buffer 和 String 转换

    字符串转为 Buffer 比较简单

    Buffer.from(string [, encoding])

    同时 Buffer 实例也有 toString 方法将 Buffer 转为字符串

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

    Buffer 拼接

    使用 concat 方法可以讲多个 Buffer 实例拼接为一个 Buffer 实例

    Buffer.concat(list[, totalLength])

    StringDecoder

    在 NodeJS 中一个汉字由三个字节表示,如果我们处理中文字符的时候使用了不是3的倍数的字节数就会造成字符拼接乱码问题。

    const buf = Buffer.from('中文字符串!');
    
    for(let i = 0; i < buf.length; i+=5){
      var b = Buffer.allocUnsafe(5);
      buf.copy(b, 0, i);
      console.log(b.toString());
    }

    这样可以看到结果中出现了乱码

    但如果使用 string_decoder 模块便可以解决这个问题

    const StringDecoder = require('string_decoder').StringDecoder;
    const decoder = new StringDecoder('utf8');
    
    const buf = Buffer.from('中文字符串!');
    
    for(let i = 0; i < buf.length; i+=5){
      var b = Buffer.allocUnsafe(5);
      buf.copy(b, 0, i);
      console.log(decoder.write(b));
    }

    StringDecoder 在得到编码后,知道宽字节在utf-8下占3个字节,所以在处理末尾不全的字节时,会保留到第二次 write()。目前只能处理UTF-8、Base64 和 UCS-2/UTF-16LE。

    Buffer 其它常用 API

    还有一些 Buffer 常用的 API

    • Buffer.isBuffer:判断对象是否为 Buffer
    • Buffer.isEncoding:判断 Buffer 对象编码
    • buf.length:返回 内存为此 Buffer 实例所申请的字节数,并不是 Buffer 实例内容的字节数
    • buf.indexOf:和数组的 indexOf 类似,返回某字符串、acsii 码或者 buf 在改 buf 中的位置
    • buf.copy:将一个 buf 的(部分)内容复制到另外一个 buf 中
  • 相关阅读:
    DataGridView 复选框 操作大全
    ClickOnce 创建桌面快捷方式
    测量程序经过的时间
    C# Js 时间格式化问题
    MVC 漫长之路(一)
    SQL 查一年内的数据
    DataRow对象的RowState和DataRowVersion属性特点
    iOS打开百度地图、高德地图导航
    NSURLCache 和 NSCache 的区别
    MagicalRecord的使用(第三方库实现的数据库)
  • 原文地址:https://www.cnblogs.com/dhsz/p/6386474.html
Copyright © 2011-2022 走看看