【Node】Buffer 与 Stream

2024-09-07 22:38
文章标签 stream node buffer

本文主要是介绍【Node】Buffer 与 Stream,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

node 为什么会出现 Buffer 这个模块

在最初的时候,JavaScript 只运行在浏览器端,

对于处理 Unicode 编码的字符串很容易,但是对于处理二进制以及非 Unicode 编码的数据便无能为力。

不过对于 Server 端操作来说 网络I/O 以及 文件I/O 的处理是必须的,所以 Node 中便提供了 Buffer 类处理二进制的数据。

二进制缓冲区 Buffer

一个 Buffer 类似于一个整数数组,可以取下标,有length属性,有剪切复制操作等,很多API也类似数组,但Buffer的大小在被创建时确定,且无法调整。

Buffer 可以与 String 互相转化,还可以设置字符集编码。

Buffer 用来处理文件 I/O、网络 I/O传输的二进制数据,String 用来呈现。

在处理文件 I/O、网络 I/O传输的二进制数据时,应该尽量以 Buffer 形式直接传输,速度会得到很好的提升。

Buffer 是一个典型的 JavaScript 与 C++ 结合的模块,与性能有关的用 C++ 来实现,JavaScript 负责衔接和提供接口。

Buffer 所占的内存不是 V8 堆内存,是独立于 V8 堆内存之外的内存,通过 C++ 层面实现内存申请。

可以说真正的内存是 C++层面提供的,而JavaScript分配内存 可以说是 JavaScript层面只是使用它。

小结:Buffer 所占用的内存不是通过 V8 分配的,属于 堆外内存

为了高效使用申请来的内存,Node 采用了 slab分配机制。slab 具有如下3种形态:

  • full:完全分配状态
  • partial:部分分配状态
  • empty:未被分配状态

Node 以 8KB 为界限来区分 Buffer 是大对象还是小对象:

Buffer.poolSize = 8 * 1024;

Buffer 对象是在 JavaScript层面的,能被 V8 的垃圾回收标记回收。

但是其内部的 parent 指向的 SlowBuffer 对象却来自于 Node 自身的 C++ 中的定义,是 C++层面上的Buffer 对象,所用内存不在 V8 的堆中。

小结:

真正的内存是在 Node 的 C++ 层面提供的,JavaScript 层面只是使用它。

当进行小而频繁的 Buffer 操作时,采用 slab 的机制进行预先申请和事后分配,使得 JavaScript 到操作系统之间不必有过多的内存申请方面的系统调用。

对于大块的 Buffer 而言,则直接使用 C++ 层面提供的内存,无需细腻的分配操作。

由于 Buffer太过常见,Node 进程在启动时就已经加载了它,并将其放在全局对象(global)上。所以在使用 Buffer时,无需通过 require() 即可直接使用。

Buffer 字符编码

通过使用字符编码,可以实现 Buffer实例与 JavaScript字符串之间的相互转换。

  • ascii —— 仅适用于7位ASCII数据。此编码速度很快,如果设置则会剥离高位。
  • utf8 —— 多字节编码的 Unicode字符。许多网页和其他文档格式都是用UTF-8。
  • base64 —— Base64编码。当从字符串创建Buffer时,此编码也会正确地接受RFC 4648第5节中指定的“URL和文件名安全字母”。
  • binary —— 一种将 Buffer编码成单字节编码字符串的方法。
  • hex —— 将每个字节编码成两个十六进制的字符。
字符串 与 Buffer类型互传

字符串转 Buffer:Buffer.from()

const buf = Buffer.from('Node.js 技术栈', 'UTF-8');console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17

Buffer 转字符串:toString([encoding], [start], [end])

const buf = Buffer.from('Node.js 技术栈', 'UTF-8');console.log(buf); // <Buffer 4e 6f 64 65 2e 6a 73 20 e6 8a 80 e6 9c af e6 a0 88>
console.log(buf.length); // 17
console.log(buf.toString('UTF-8', 0, 9)); // 'Node.js �'

运行查看,可以看到以上输出结果为 Node.js �, 出现了乱码。

转换过程中为什么出现乱码?

问题出在这里一个中文在UTF-8下占用3个字节,“技”这个字在 buf 中对应的字节为 8a80e6,而我们设定的范围为0~9,

因此只输出了8a,这个时候就会造成字符被截断,出现乱码的情况。要想完整出现“技”这个字,则应该截取到11位。

console.log(buf.toString('UTF-8', 0, 11)); // 'Node.js 技'
Buffer 的拼接

Buffer 在使用场景中,通常是以一段一段的方式传输。

var fs = require('fs');var rs = fs.createReadStream('test.txt');
var dat

这篇关于【Node】Buffer 与 Stream的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146363

相关文章

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

Node Linux相关安装

下载经编译好的文件cd /optwget https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.gztar -xvf node-v10.15.3-linux-x64.tar.gzln -s /opt/node-v10.15.3-linux-x64/bin/npm /usr/local/bin/ln -s /opt/nod

JavaSE(十三)——函数式编程(Lambda表达式、方法引用、Stream流)

函数式编程 函数式编程 是 Java 8 引入的一个重要特性,它允许开发者以函数作为一等公民(first-class citizens)的方式编程,即函数可以作为参数传递给其他函数,也可以作为返回值。 这极大地提高了代码的可读性、可维护性和复用性。函数式编程的核心概念包括高阶函数、Lambda 表达式、函数式接口、流(Streams)和 Optional 类等。 函数式编程的核心是Lambda

在Debian 8上安装Node.js的方法

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 Node.js 是一个通用编程的 JavaScript 平台,允许用户快速构建网络应用程序。通过在前端和后端都使用 JavaScript,开发可以更加一致,并且可以在同一个系统中设计。 在本指南中,您将在 Debian 8 服务器上安装 Node.js。Debian 8 包含一个版本的

使用Node-API进行异步任务开发

一、Node-API异步任务机制概述         Node-API异步任务开发主要用于执行耗时操作的场景中使用,以避免阻塞主线程,确保应用程序的性能和响应效率。         1、应用场景: 文件操作:读取大型文件或执行复杂的文件操作时,可以使用异步工作项来避免阻塞主线程。网络请求:当需要进行网络请求并等待响应时,可以使用异步工作项来避免阻塞主线程,从而提高应用程序的响应性能。数据库操

Java 文件读写最好是用buffer对于大文件可以加快速度

参考例子: FileReader fileReader = new FileReader(filename);BufferedReader bufferedReader = new BufferedReader(fileReader);List<String> lines = new ArrayList<String>();String line = null;while ((line =

Node.js学习记录(一)

目录 一、文件读取 readFile 二、写入文件 writeFile 三、动态路径 __dirname:表示当前文件所处的目录、path.join 四、获取路径文件名 path.basename 五、提取某文件中的css、JS、html 六、http 七、启动创建web服务器 服务器响应 八、将资源请求的 url 地址映射为文件的存放路径 九、模块 模块加载 模块作用域

ubuntu安装node的问题

初学node,按照书上的流程安装nodejs,当安装canvas的时候(npm install canvas)遇到问题 node-gyp rebuild 然后就卡住了,查了下,基本上就是各种依赖问题,几经折腾就在要放弃的时候,终于在网上发现node官方wike https://github.com/Automattic/node-canvas/wiki/Installation---Ubun

Java stream使用与执行原理

stream简介 Stream: A sequence of elements supporting sequential and parallel aggregate operations stream为sequential即单线程串行操作,parallelStream支持并行操作,本文只讨论sequential的stream。 stream常用操作 @Datastatic

node快速复制文件或文件夹,排除部分文件(node_modules)

const fs = require('fs')const path = require('path')/*** @description: 获取完整的文件路径* @param {*} url 路径* @return {*} 返回完整的文件路径*/const getPath = (url) => {return path.join(__dirname, url)}/*** @descr