再见Node.js缓冲区,是时候从 Buffer 转移到 Uint8Array 了

更新日期: 2023-11-09阅读: 352标签: 进制

从一开始,该Buffer类型就一直是 Node.js 中二进制数据处理的基石。然而,现在我们有了Uint8Array,它是一种原生 JavaScript 类型并且可以跨平台工作。虽然Buffer是 的一个实例Uint8Array,但它引入了许多在其他 JavaScript 环境中不可用的方法。因此,利用特定于 Buffer 的方法的代码需要进行多填充,从而阻止许多有价值的包与浏览器兼容。

Buffer还带有额外的警告。在Uint8Array#slice()创建不可变副本时,Buffer#slice()会创建链接到原始缓冲区的可变段,从而导致可能出现不可预测的行为。问题不在于方法的行为Buffer#slice(),而在于它Buffer是继承方法的子类Uint8Array并完全改变了继承方法的行为。Buffer#slice()请使用Uint8Array#subarray()或来代替Buffer#subarray()。此外,缓冲区通过全局变量暴露私有信息,这是一个潜在的安全风险。

是时候继续前进了。


计划

我打算将所有包从Bufferusing移至Uint8Array. 如果您是 JavaScript 包的维护者,我鼓励您也这样做。

Buffer永远不会被删除,甚至可能永远不会被弃用,但至少社区可以慢慢摆脱它。我希望 Node.js 团队至少会开始阻止使用Buffer.


如何

首先,熟悉和之间微妙的不兼容性。Uint8ArrayBuffer

我制作了这个uint8array-extras包以使过渡更容易。欢迎请求其他实用程序。

如果您的代码接受 aBuffer并且不使用任何Buffer特定于 的方法,您只需将文档和类型更新为Uint8Array. 将输入类型从Bufferto更改Uint8Array为非破坏性更改,因为Buffer是 的实例Uint8Array。

将返回类型从 更改Buffer为Uint8Array是一个重大更改,因为消费者可能会使用Buffer特定的方法。

如果您确实需要将 a 转换Uint8Array为 a Buffer,则可以使用Buffer.from(uint8Array)(复制数据) 或Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength)(不复制)。然而,通常有更好的方法。

主要过渡步骤是:

  • 删除所有import {Buffer} from 'node:buffer'导入。
  • 删除所有出现的Buffer全局。
  • 停止使用Buffer特定方法。
  • 替换Buffer读/写方法。


问题

Buffer最初为什么存在?

Buffer早在Uint8Array存在之前就被创建了。

如何使用 Base64 进行转换Uint8Array?

你现在可以使用我的uint8array-extras包。它很可能最终会在 JavaScript 中得到原生支持。

如何处理返回 a 的 Node.js api Buffer(如fs方法)?

由于Buffer是 的子类Uint8Array,因此您可以将其视为Uint8Array. 只需确保您不使用.slice()(行为不同)或任何特定于缓冲区的方法。


例子

JavaScript

+import {stringToBase64} from 'uint8array-extras';

-Buffer.from(string).toString('base64');
+stringToBase64(string);
+import {uint8ArrayToHex} from 'uint8array-extras';

-buffer.toString('hex');
+uint8ArrayToHex(uint8Array);
 const bytes = getBytes();

+const view = new DataView(bytes.buffer);

-const value = bytes.readInt32BE(1);
+const value = view.getInt32(1);
 import crypto from 'node:crypto';
-import {Buffer} from 'node:buffer';
+import {isUint8Array} from 'uint8array-extras';

 export default function hash(data) {
-	if (!(typeof data === 'string' || Buffer.isBuffer(data))) {
+	if (!(typeof data === 'string' || isUint8Array(data))) {
 		throw new TypeError('Incorrect type.');
 	}

 	return crypto.createHash('md5').update(data).digest('hex');
 }

大多数 Node.js APIUint8Array也接受,因此不需要额外的工作。理想情况下,此代码还应转换为Web Crypto,但这与本示例无关。

TypeScript

-import {Buffer} from 'node:buffer';

-export function getSize(input: string | Buffer): number { … }
+export function getSize(input: string | Uint8Array): number { … }


执行

我建议强制执行Uint8Arraylinting Buffer。

将其添加到您的 ESLint 配置中:

{
	'no-restricted-globals': [
		'error',
		{
			name: 'Buffer',
			message: 'Use Uint8Array instead.'
		}
	],
	'no-restricted-imports': [
		'error',
		{
			name: 'buffer',
			message: 'Use Uint8Array instead.'
		},
		{
			name: 'node:buffer',
			message: 'Use Uint8Array instead.'
		}
	]
}

如果您使用 TypeScript,请添加以下内容:

{
	'@typescript-eslint/ban-types': [
		'error',
		{
			types: {
				Buffer: {
					message: 'Use Uint8Array instead.',
					suggest: [
						'Uint8Array'
					]
				}
			}
		}
	]
}

如果您使用XO,它很快就会默认带有此配置。

翻译来自:https://sindresorhus.com/blog/goodbye-nodejs-buffer

链接: https://www.fly63.com/article/detial/12548

二进制和十进制相互转换、位移运算

自己的解题思路是将十进制的数转为二进制(不足32位补0),然后依次取8位转化为十进制的数字,再用.连接即为IP。里面的几个点记录一下:十进制转换为二进制 numObj.toString([radix]) radix可以指定进制

Js进制转换

参数radix支持 [2, 36] 之间的整数。例如:参数值为2,则表示二进制;为8,则表示八进制;为16,则表示十六进制。如果省略参数radix,则默认为10(十进制)。

理解二进制操作

最近在用 shell 写一个小工具,里面要用到复杂的二进制操作,对 int 值进行位操作和与或非,而 shell 的语法里, & 是取布尔与, >> 是重定向,不支持二进制操作,为了写出只需要默认系统环境就可以运行的程序

js 进制转换/进制编码解码

js 进制转换支持 2-36 , 即 0-9a-z .可以用于混淆、数值缩短、特殊符号转换…字符串36进制编码解码;ip地址端口号36进制编码解码

Js将十进制转换为十六进制?

JavaScript中有很多内置函数可以帮我们进行数(进)制转换。那么给定一个十进制数字,如何将数字从十进制转换为十六进制?下面本篇文章就来给大家介绍一个使用JavaScript将十进制转换为十六进制的方法

JavaScript 进制转换&位运算

在一般的代码中很少会接触到进制和位运算,但这不代表我们可以不去学习它。作为一位编程人员,这些都是基础知识。如果你没有学过这方面的知识,也不要慌,接下来的知识并不会很难。本文你将会学习到:进制转换,按位操作符,Javascript进制转换

nodejs怎么存取2进制数据?

在客户端javascript脚本代码中,对于二进制数据并没有提供一个很好的支持。然后在nodejs中需要处理像TCP流或文件流时,必须要处理二进制数据。因此在node.js中,定义了一个Buffer类,该类用来创建一个专门存放二进制数据的缓存区

十进制与十六进制之间的转换

将十进制数 x 除以 16, 即 x = q * 16 + r,取得余数 r 和 商 q,此时余数 r 就是 x 用十六进制表示时的最低位值; 之后商值 q 继续进行以上的除法操作, 获取每次的余数 r 作为 十六进制表示时的低位值, 直到 q 值小于 16 为值, 此时的

二进制数与位运算符

位运算符是基于二级制数进行操作的,即表示数字的 32 个数位,它由0和1组成…ECMAScript整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数)

JavaScript中的多种进制与进制转换

JavaScript 中提供的进制表示方法有四种:十进制、二进制、十六进制、八进制。对于数值字面量,主要使用不同的前缀来区分:

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!