前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >js操作二进制数据

js操作二进制数据

作者头像
风花一世月
发布于 2024-03-19 06:03:21
发布于 2024-03-19 06:03:21
31900
代码可运行
举报
文章被收录于专栏:前端前端
运行总次数:0
代码可运行

使用ArrayBuffer对象保存二进制数据,使用TypedArray和DataView 视图来读写数据。

ArrayBuffer代码内存中的一段数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const buff = new ArrayBuffer(4)

这样就创建了一个4(byte)字节的长度的内存判断,初始值都为0

注:一般中文占2个字节,英文占1个字节。不同的编码会不同比如:中文在UTF-8占3个字节、在UTF-16中占4个字节

ArrayBuffer属性和方法

一个属性:byteLength,获取他里面数据的字节数和

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
buff.byteLength
// 4

一个方法:slice,和数组slice一个用于拷贝一段内存

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
buff.slice(1,3)
// ArrayBuffer(2)
// 拷贝了 buff 里下标 1、2 的内存数据

ArrayBuffer不能直接读写,只是放数据的容器,不能直接对内存数据进行读写,因为操作二进制数据可以有多种不同的数据类型、他们字节长度、值范围都不相同,不指定类型,不能读写内存数据

如:

 Uint8是8位不带符号整数,值范围是 0 到 255 ,长度为1Byte

 而 Int32 是有符号整数,值范围是 -2,147,483,648 到 +2,147,483,647,长度为 4 Byte。

ArrayBuffer 支持使用以下 9 种类型来读写内存数据:

  • Int8 8位带符号整数 signed char
  • Uint8 8位不带符号整数 unsigned char
  • Uint8C 8位不带符号整数(自动过滤溢出) unsigned char
  • Int16 16位带符号整数 short
  • Uint16 16位不带符号整数 unsigned short
  • Int32 32位带符号整数 int
  • Uint32 32位不带符号的整数 unsigned int
  • Float32 32位浮点数 float
  • Float64 64位浮点数 double

TypedArray

TypedArray 可以将一段 ArrayBuffer 的数据全部使用我们设定的类型来操作。

创建 TypedArray

TypedArray 可以使用 9 种类型,每个类型有对应的构造函数:

  • Int8Array:8位有符号整数,长度1个字节。
  • Uint8Array:8位无符号整数,长度1个字节。
  • Uint8ClampedArray:8位无符号整数,长度1个字节,溢出处理不同。
  • Int16Array:16位有符号整数,长度2个字节。
  • Uint16Array:16位无符号整数,长度2个字节。
  • Int32Array:32位有符号整数,长度4个字节。
  • Uint32Array:32位无符号整数,长度4个字节。
  • Float32Array:32位浮点数,长度4个字节。
  • Float64Array:64位浮点数,长度8个字节。

构造函数接收一个 ArrayBuffer 对象,将其转换成指定类型的二进制数组。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new (array: ArrayBufferLike | ArrayLike<number>, byteOffset?: number | undefined, byteLength?: number | undefined) => TypedArray

同一个 ArrayBuffer 可以生成多个不同类型的 TypedArray

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const buff = new ArrayBuffer(4)
// 申请了长度为 4 字节的内存

const uInt8 = new Uint8Array(buff)
// 创建了长度为 4 的数组 (因为 Uint8 的单位长度是 1 字节)

const int32 = new Int32Array(buff)
// 创建了长度为 1 的数组(因为 Int32Array 的单位长度是 4 字节)

// 如果有需要,也可以设定起始位置的偏移量,以及从起始位置开始的内存长度
const uInt8 = new Uint8Array(buff, 1, 2)

操作 TypedArray

TypedArray 是类数组对象,我们可以使用数组的方式来操作,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 读
uInt8[0]

// 写
uInt8[0] = 1

// 数组方法
uInt8.findIndex(val=>val===0)

注意:

使用 ArrayBuffer 数据创建 TypedArray 时,生成的 TypedArray 对象数组只是对 ArrayBuffer 的引用。

TypedArray 的属性

  • buffer:保存着这个 TypedArray 操作的 ArrayBuffer 对象。所以从 TypedArray 对象里返回其数据时,要使用它的 buffer 属性。
  • byteOffset:起始位置的偏移量
  • byteLength:字节长度,也就是内存使用量。
  • length:数组长度,根据类型不同,数组长度也不同。

例如 4 字节的 byteLength,以 Uint8Array 读取则 length 为 4,以 Int32Array 读取则 length 为 1。

DataView

DataView 和 TypedArray 的区别

DataView 和 TypedArray 有一些区别:

  • TypedArray 把整个 ArrayBuffer 全部视为某种指定的类型,而 DataView每次操作都必须手动指明类型,所以它可以灵活使用多种类型。
  • TypedArray 是类数组对象,但 DataView 不是类数组对象,所以不能使用数组的方法。
  • TypedArray 不能设定字节序(总是小端),而 DataView 可以设定字节序(大端或小端)(默认小端)。

创建 DataView

使用 DataView 构造函数来创建一个 DataView 对象。

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new (buffer: ArrayBufferLike, byteOffset?: number | undefined, byteLength?: number | undefined) => DataView

简单示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const view = new DataView(buff)

// 如果有需要,也可以设定起始位置的偏移量,以及从起始位置开始的内存长度
const view = new DataView(buff, 2, 2)

由于创建 DataView 对象时不能指定类型,所以我们在操作时必须手动指定类型。

DataView 只有对内存的读、写操作,而且要使用指定的方法。它不能像 TypedArray 那样使用数组下标和数组方法。

DataView 读内存

DataView 实例提供 8 个方法读取内存。

  • getInt8 读取 1 个字节,返回一个 8 位整数。
  • getUint8 读取 1 个字节,返回一个无符号的 8 位整数。
  • getInt16 读取 2 个字节,返回一个 16 位整数。
  • getUint16 读取 2 个字节,返回一个无符号的 16 位整数。
  • getInt32 读取 4 个字节,返回一个 32 位整数。
  • getUint32 读取 4 个字节,返回一个无符号的 32 位整数。
  • getFloat32 读取 4 个字节,返回一个 32 位浮点数。
  • getFloat64 读取 8 个字节,返回一个 64 位浮点数。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const view = new DataView(buff)

view.getUint8(0)

view.getUint16(1)
// DataView.getUint16(byteOffset: number, littleEndian?: boolean | undefined): number

// 使用大端字节序
view.getUint32(2, false)

第一个参数是读取的内存的位置;

第二个参数是可选参数,用来指定字节序。只有当一次性读取超过 1 字节时才有这个参数。

DataView 默认使用小端字节序。如果你要使用大端字节序,必须把第二个参数设置为 false

DataView 写内存

DataView 写内存的方法也是 8 个,与读内存的 8 个方法对应。

  • setInt8 写入 1 个字节的 8 位整数。
  • setUint8 写入 1 个字节的 8 位无符号整数。
  • setInt16 写入 2 个字节的 16 位整数。
  • setUint16 写入 2 个字节的 16 位无符号整数。
  • setInt32 写入 4 个字节的 32 位整数。
  • setUint32 写入 4 个字节的 32 位无符号整数。
  • setFloat32 写入 4 个字节的 32 位浮点数。
  • setFloat64 写入 8 个字节的 64 位浮点数。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const view = new DataView(buff)

// DataView.setInt8(byteOffset: number, value: number): void
view.setInt8(0, 0xbb)

// DataView.setInt16(byteOffset: number, value: number, littleEndian?: boolean | undefined): void
view.setInt16(4, 1, true)

view.setInt32(8, 520, true)

DataView 的属性

  • buffer:保存着这个 DataView 操作的 ArrayBuffer 对象。所以从 DataView 对象里返回其数据时,要使用它的 buffer 属性。
  • byteOffset:起始位置的偏移量
  • byteLength:字节长度,也就是内存使用量。

DataView 不是类数组对象,所以没有 length 属性。

一些应用方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// ArrayBuffer转16进度字符串示例
ab2hex(buffer) {
    const hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function(bit) {
            return ('00' + bit.toString(16)).slice(-2)
        }
    )
    return hexArr.join('')
},
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 16进制字符串转ArrayBuffer
hex2ArrayBuffer(hex_str) {
    let typedArray = new Uint8Array(hex_str.match(/[\da-f]{2}/gi).map(function(h) {
        return parseInt(h, 16)
    }))
    let buffer = typedArray.buffer
    return buffer
},
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JS中的二进制数据处理
  在现有的计算机中,二进制常常以字节数组的形式存在于程序当中。例如在C#里面,就用byte[],标准C里面没有byte类型,但可以通过typedef把byte定义为unsigned char的别名,效果是一样的。JS设计之初似乎就没想过要处理二进制,对于字节的概念可以说是非常非常的模糊。如果要表达字节数组,那么似乎只能用一个普通数组来表示。
有赞coder
2021/05/13
3.8K0
JS中的二进制数据处理
ArrayBuffer
ArrayBuffer对象、TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口。这些对象早就存在,属于独立的规格(2011 年 2 月发布),ES6 将它们纳入了 ECMAScript 规格,并且增加了新的方法。它们都是以数组的语法处理二进制数据,所以统称为二进制数组。 这个接口的原始设计目的,与 WebGL 项目有关。所谓 WebGL,就是指浏览器与显卡之间的通信接口,为了满足 JavaScript 与显卡之间大量的、实时的数据交换,它们之间的数据通信必须是二进制的,而不能是传统的文本格式。文本格式传递一个 32 位整数,两端的 JavaScript 脚本与显卡都要进行格式转化,将非常耗时。这时要是存在一种机制,可以像 C 语言那样,直接操作字节,将 4 个字节的 32 位整数,以二进制形式原封不动地送入显卡,脚本的性能就会大幅提升。
小小杰啊
2022/12/21
2.6K0
前端二进制文件处理
上一篇文章从 W3C 草案的角度入手过了一遍 File API 的几个方法,这一篇尝试梳理一下二进制数据相关的一些方法,有 Blob、ArrayBuffer、Uint8Array、BufferSource 等。
上山打老虎了
2022/06/15
1.6K0
前端二进制文件处理
web 直播流的解析
本文作者:ivweb villainthr Web 进制操作是一个比较底层的话题,因为平常做业务的时候根本用不到太多,或者说,根本用不到。 老铁,没毛病 那什么情况会用到呢? canvas webso
腾讯IVWEB团队
2017/07/14
4K2
web 直播流的解析
JavaScript中的二进制数据
在我编写 js 代码中,关于处理二进制数据了解甚少,好像都是用数组表示,但是成员又很模糊。尤其是在遇到一些 http 的 post 请求或 websocket,发送二进制数据(字节)时,还有一些算法的翻译,数据的转化,协议的复现,都需要不断的从网络上查阅,并未系统的从文档教程中入手。于是写这篇的目的就是为了加固对二进制数据的理解,以及 JavaScript 中如何操作二进制数据的。
愧怍
2022/12/27
2.3K0
Blob、File、ArrayBuffer、TypedArray、DataView究竟应该如何应用
Blob、File、ArrayBuffer、TypedArray、DataView、Object URL ..等等 Web 应用中有关于进制的应用你了解多少?
19组清风
2022/05/11
2K0
Blob、File、ArrayBuffer、TypedArray、DataView究竟应该如何应用
使用ES6新特性开发微信小程序(4)
Symbol Type ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。 Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型。凡是属性名属于Symbol类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。 let s =
极乐君
2018/02/05
1.8K0
从图片裁剪来聊聊前端二进制
首先判断window.navigator.msSaveOrOpenBlob是为了兼容IE(谁要兼容这 xxIE!!)
前端森林
2020/08/21
1.7K0
从图片裁剪来聊聊前端二进制
​DataView 对象:JavaScript 中的数据处理利器
在 JavaScript 中,我们经常需要处理大量的数据,包括从后端获取的数据、用户输入的数据等等。而在处理这些数据的时候,我们经常需要对数据进行排序、筛选、分组等操作。这时候,DataView 对象就成为了我们的得力助手。本文将详细介绍 DataView 对象的使用方法,并给出具体的实例。
Front_Yue
2023/12/31
2.1K0
​DataView 对象:JavaScript 中的数据处理利器
万字长文带你学习【前端开发中的二进制数据】| 技术创作特训营第五期
在现代前端开发中,处理二进制数据变得越来越重要。从图像、音频到文件上传,这些数据类型常常以二进制形式存在。这个分享将带你深入探索 ArrayBuffer、Blob、File 以及流(Stream)等概念,探讨它们如何在前端开发中发挥作用,解锁了解和利用二进制数据的强大能力。
程序员库里
2024/01/24
7770
JavaScript 高级程序设计(第 4 版)- 集合引用类型
定型数组同样使用数组缓冲来存储数据,而数组缓冲无法调整大小,故以下方法不适用于定型数组
Cellinlab
2023/05/17
7380
深入学习 Node.js Buffer
ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。ArrayBuffer 不能直接操作,而是要通过类型数组对象 或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
阿宝哥
2019/11/06
1.8K0
深入学习 Node.js Buffer
DOMString、Document、FormData、Blob、File、ArrayBuffer (转)
我大学那会儿,一个称为Ajax的东西对前端行业造成了深远影响,不仅是JS语言,而包括前端地位、职位兴起以及工作分工等。抛开IE6浏览器不谈,其他浏览器的Ajax实际上都是借助XMLHttpRequest实现的。
javascript.shop
2019/09/04
3K0
DOMString、Document、FormData、Blob、File、ArrayBuffer (转)
不再碎片化学习,快速掌握 H5 直播技术
现在,大多数已工作的前端工作者的学习方式,要么直接到 Stackoverflow 上搜代码,要么直接看看相关博文。这样是快,但是零零碎碎只是一个一个孤立的知识点而已。有可能一下午都忘记了,唯一可能记住的收藏一下那个文章,然后就彻底躺尸了。那有没有啥更好的办法能解决呢? 当然有,第一,有时间,第二,有人指导,第三,找对资料。 这其实和看书是一样的,一本书,最有价值的地方不在它的内容或者作者,而在于它的 目录,是否真正的打动你。如果只是出现一些模糊而没有落地技术的目录的书籍,还是别再上面浪费时间了。 所以,本文
villainhr
2018/07/03
1.7K0
WebSocket系列之JavaScript中数字数据如何转换为二进制数据
本文主要通过对JavaScript中数字数据与二进制数据之间的转换,让读者能够了解在JavaScript中如何对数字类型(包括但不限于Number类型)进行处理。
黄Java
2018/09/18
2.5K0
深度学习的JavaScript基础:矩阵和向量的表示
与Java、C++这样的静态类型语言不同,JS中的变量似乎没有类型,在声明变量时不用指定变量类型。但实际上JS也有字符串、数字、布尔值、对象、数组、未定义等类型,是一种弱类型语言。在深度学习中,矩阵和向量是最基本的数据结构,而高效的矩阵和向量运算是深度学习计算中的关键。在C++中,数组可用于表示矩阵或向量,JS中也有这样的数据结构吗?
云水木石
2019/12/18
2.3K0
内功修炼之lodash—— clone&cloneDeep(一定有你遗漏的js基础知识)
本文实现方法都是看效果倒推实现方法,并进行一些拓展和思考,和源码无关。lodash这个库在这里更像一个题库,给我们刷题的
lhyt
2019/11/19
5.5K0
JavaScript中Array怎么用?
Array 是 JavaScript 的全局数组对象,其元素可以是不同类型,如果需要元素是同一类型,可使用 TypedArray。
Learn-anything.cn
2021/12/20
1.5K0
谁说前端不需要懂二进制
作为一名前端,在工作中也会遇到很多有关二进制处理的需求,如 EXCEL 表格的导出,PDF 的生成,多个文件的打包,音频的处理。
山月
2020/06/18
1.2K0
开心档之Node.js Buffer(缓冲区)
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
爱学iOS的小麦子
2023/02/09
1.2K0
推荐阅读
相关推荐
JS中的二进制数据处理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验