js二进制数据,文件---ArrayBuffer,二进制数组

1.二进制数据        

        在 JavaScript 中有很多种二进制数据格式,比如:ArrayBufferUint8ArrayDataViewBlobFile 及其他。

2.ArrayBuffer

        基本的二进制对象是 ArrayBuffer —— 对固定长度的连续内存空间的引用ArrayBuffer 是核心对象,是所有的基础,是原始的二进制数据

let buffer = new ArrayBuffer(16);// 分配一个 16 字节的连续内存空间,并用 0 进行预填充。
console.log(buffer);// 内部是空值,仅开辟了空间

要注意的是:

ArrayBuffer 不是某种东西的数组(array 只是形容,表这个数据是连续的字节流)

让我们先澄清一个可能的误区。ArrayBuffer 与 Array 没有任何共同之处

  • 它的长度是固定的,我们无法增加或减少它的长度。
  • 它正好占用了内存中的那么多空间。
  • 要访问单个字节,需要另一个“视图”对象,而不是 buffer[index]

可以查看打印的结果:

        打印结果包括了一个8位的视图内容(视图是将字节流可视化,让我们能够操作这个字节空间),还有字节流的长度。

        可以看到我们并不能直接对ArrayBuffer进行操作,连打印结果都是转换成视图展示。而真正要对ArrayBuffer进行操作也正是需要视图(view)

3.视图(view)

        操作 ArrayBuffer,我们需要使用“视图”对象。

        视图对象本身并不存储任何东西。它是一副“眼镜”,透过它来解释存储在 ArrayBuffer 中的字节,例如:

  • Uint8Array —— 将 ArrayBuffer 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位,因此只能容纳那么多)。这称为 “8 位无符号整数”。
  • Uint16Array —— 将每 2 个字节视为一个 0 到 65535 之间的整数。这称为 “16 位无符号整数”。
  • Uint32Array —— 将每 4 个字节视为一个 0 到 4294967295 之间的整数。这称为 “32 位无符号整数”。
  • Float64Array —— 将每 8 个字节视为一个 5.0x10-324 到 1.8x10308 之间的浮点数。

// 通过视图(view)来对二进制数据操作
let view = new Uint32Array(buffer); // 将每 4 个字节视为一个 0 到 4294967295 之间的整数。这称为 “32 位无符号整数”
console.log("视图:",view,"视图存储整数的个数:",view.length,"视图检查的二进制数据流的字节长度:",view.byteLength);// 类数组
view[0] = 1000;
console.log(view,buffer);// 第一个位置存入了100

通过view我们可以直观的看到ArrayBuffer的空间大小和内容,以及存放遍历数据(类数组)

4.TypedArray

        所有这些视图(Uint8ArrayUint32Array 等)的通用术语(总称)是 TypedArray。它们共享同一方法和属性集,以下都属于TypedArray

  • Uint8ArrayUint16ArrayUint32Array —— 用于 8 位、16 位和 32 位无符号整数。
  • Uint8ClampedArray —— 用于 8 位整数,在赋值时便“固定”其值。
  • Int8ArrayInt16ArrayInt32Array —— 用于有符号整数(可以为负数)。
  • Float32ArrayFloat64Array —— 用于 32 位和 64 位的有符号浮点数。

        注意,没有名为 TypedArray 的构造器(以下构造方法只是引用,并没有new TypedArray的构造方法,应该使用new Uint32Array,new Uint8Array),它只是表示 ArrayBuffer 上的视图之一的通用总称术语:Int8ArrayUint8Array 及其他,当你看到 new TypedArray 之类的内容时,它只是代替 new Int8Array(8位整数)new Uint8Array (8位无符号整数)及其他中之一。

类型化数组的行为类似于常规数组:具有索引,并且是可迭代的。

它有5中构造方法

new TypedArray(buffer, [byteOffset], [length]);
new TypedArray(object);
new TypedArray(typedArray);
new TypedArray(length);
new TypedArray();
  1. 如果给定的是 ArrayBuffer 参数,则会在其上创建视图。上面已经用过这个语法了。

        参数1ArrayBuffer,一个二进制数据对象,参数2:可选,给定视图读取的起始位置 (默认为 0),参数3:可选, 视图读取的长度(默认至 buffer 的长度)

let viewT1 = new Uint32Array(buffer,0,2);
console.log(viewT1);

对比默认的参数,这里是从第0位开始读取2位数据。

        2.如果给定的是 Array,或任何类数组对象,则会创建一个相同长度的类型化数组,并复制其内容,我们可以使用它来预填充数组的数据

let viewT2 = new Uint8Array([0,1,2,3]);
console.log(viewT2);

        3.如果给定的是另一个 TypedArray,也是如此:创建一个相同长度的类型化数组,并复制其内容。

let viewT3 = new Uint16Array(viewT1);
console.log(viewT3);

可以看到直接复制了一份viewT1的内容,但是转换了格式(32->16)

4.对于数字参数 length —— 创建指定长度的类型化数组,并用0默认填充内容。

let viewT4 = new Uint8Array(6);
console.log(viewT4);

5.不带参数的情况下,创建长度为零的类型化数组,定义变量类型。

 TypedArray 的属性:

  • view.buffer —— 读取的对应ArrayBuffer
  • view.byteLength —— ArrayBuffer 的长度。
let view = new Uint32Array(buffer); // 将每 4 个字节视为一个 0 到 4294967295 之间的整数。这称为 “32 位无符号整数”
console.log("视图:",view,"视图存储整数的个数:",view.length,"视图检查的二进制数据流的字节长度:",view.byteLength,"视图读取的二进制数据流:",view.buffer);// 类数组

越界行为

        当对视图进行转换时,可能出现长度越界,例如,我们尝试将 256 放入 Uint8Array。256 的二进制格式是 100000000(9 位),但 Uint8Array 每个值只有 8 位,最终数字1会被移除,只保留后面的8个0,如果刚好1是符号位,那么就可能会出现正负转换(这就是计算时数据太大,正数加成负数的原因)

256和257最终变成 0和1

TypedArray 的方法:

   TypedArray 具有常规的 Array 方法,但有个明显的例外。我们可以遍历(iterate),mapslicefind 和 reduce 等:

  • arr.set(fromArr, [offset]) 从 offset(默认为 0)开始,将 fromArr 中的所有元素复制到 arr
  • arr.subarray([begin, end]) 创建一个从 begin 到 end(不包括)相同类型的新视图。这类似于 slice 方法(同样也支持),但不复制任何内容 —— 只是创建一个新视图,以对给定片段的数据进行操作。

但有几件事我们做不了:

  • 没有 splice —— 我们无法“删除”一个值,因为类型化数组是缓冲区(buffer)上的视图,缓冲区表示的计算机中的0,1数据,这是硬件决定的,我们不能将硬件删除。我们所能做的就是分配一个零值表示这个数据是空的,只能置零不能删除
  • 无 concat 方法。
// (销毁数据)遍历视图,将二进制数据置零
function delData(view){view.map((item,index,array)=>{array[index] = 0;});
}
delData(view);
console.log(view);

这样就实现了删除数据的效果

5.DataView

        DataView是在 ArrayBuffer 上的一种特殊的超灵活“未类型化”视图。它允许以其他任何格式(8位,16位,32位,等)访问任意长度的数据。

        对于类型化的数组,构造器决定了其格式,只能访问当前格式的数据(8位的数据的数组,只能拿到8位的数据

        通过 DataView,我们可以使用 .getUint8(i) 或 .getUint16(i) 之类的方法访问数据。我们在调用方法时选择格式,而不是在构造的时候。

new DataView(buffer, [byteOffset], [byteLength])
buffer —— 底层的 ArrayBuffer。与类型化数组不同,DataView 不会自行创建缓冲区(buffer)。我们需要事先准备好。
byteOffset —— 视图的读取的起始位置(默认为 0)。
byteLength —— 视图的读取长度(默认至 buffer 的末尾)。

// 4 个字节的二进制数组,每个都是最大值 255,一串都为1的二进制数据
let bufferData = new Uint8Array([255, 255, 255, 255]).buffer;// 通过视图得到二进制数据
console.log(bufferData);let dataView = new DataView(bufferData);
console.log(dataView.getUint8(0),dataView.getUint16(0),dataView.getUint32(0))
dataView.setUint32(0, 0); // 将 4 个字节的数字设为 0,即将所有字节都设为 0
console.log(dataView.getUint32(0));

        用 DataView 可以轻松访问一个ArrayBuffer 的任意视图格式(8位,16位,32位,等)的内容,这拥有很高的灵活性

6.总结

  ArrayBuffer 是核心对象,是对固定长度的连续内存区域的引用,几乎任何对 ArrayBuffer 的操作,都需要一个视图。它可以是 TypedArray,或者或 DataView

完整代码和结果

let buffer = new ArrayBuffer(16);// 分配一个 16 字节的连续内存空间,并用 0 进行预填充。
console.log(buffer);// 内部是空值,仅开辟了空间
// 通过视图(view)来对二进制数据操作
let view = new Uint32Array(buffer); // 将每 4 个字节视为一个 0 到 4294967295 之间的整数。这称为 “32 位无符号整数”
console.log("视图:",view,"视图存储整数的个数:",view.length,"视图检查的二进制数据流的字节长度:",view.byteLength,"视图读取的二进制数据流:",view.buffer);// 类数组
view[0] = 1000;
console.log(view,buffer);// 第一个位置存入了100// 视图的构造方法
let viewT1 = new Uint32Array(buffer,0,2);
console.log(viewT1);let viewT2 = new Uint8Array([0,1,2,3]);
console.log(viewT2);let viewT3 = new Uint16Array(viewT1);
console.log(viewT3);let viewT4 = new Uint8Array(6);
console.log(viewT4);// (销毁数据)遍历视图,将二进制数据置零
function delData(view){view.map((item,index,array)=>{array[index] = 0;});
}
console.log(view);
delData(view);
console.log(view);console.log("------------");// 4 个字节的二进制数组,每个都是最大值 255,一串都为1的二进制数据
let bufferData = new Uint8Array([255, 255, 255, 255]).buffer;// 通过视图得到二进制数据
console.log(bufferData);let dataView = new DataView(bufferData);
console.log(dataView.getUint8(0),dataView.getUint16(0),dataView.getUint32(0))
dataView.setUint32(0, 0); // 将 4 个字节的数字设为 0,即将所有字节都设为 0
console.log(dataView.getUint32(0));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/330415.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux:信号深入理解

文章目录 1.信号的概念1.1基本概念1.2信号的处理基本概念1.3信号的发送与保存基本概念 2.信号的产生2.1信号产生的五种方式2.2信号遗留问题(core,temp等) 3.信号的保存3.1 信号阻塞3.2 信号特有类型 sigset_t3.3 信号集操作函数3.4 信号集操作函数的使用 4.信号的处理4.1 信号的…

Qt输入输出类使用总结

Qt输入输出类简介 QTextStream 类(文本流)和 QDataStream 类(数据流)Qt 输入输出的两个核心类,其作用分别如下: QTextStream 类:用于对数据进行文本格式的读/写操作,可在 QString、QIODevice或 QByteArray 上运行,比如把数据输出到 QString、QIODevice 或 QByteArray 对象…

Ubuntu切换内核版本

#安装内核安装工具 sudo apt-get install software-properties-common sudo add-apt-repository ppa:cappelikan/ppa sudo apt-get update sudo apt-get install mainline#安装指定内核版本(有些版本并不能安装成功) mainline install 5.14.10#更新GRUB配置 sudo update-grub#查…

Python实现将LabelMe生成的JSON格式转换成YOLOv8支持的TXT格式

标注工具 LabelMe 生成的标注文件为JSON格式,而YOLOv8中支持的为TXT文件格式。以下Python代码实现3个功能: 1.将JSON格式转换成TXT格式; 2.将数据集进行随机拆分,生成YOLOv8支持的目录结构; 3.生成YOLOv8支持的YAML文件…

操作教程|通过DataEase开源BI工具对接金山多维表格

前言 金山多维表格是企业数据处理分析经常会用到的一款数据表格工具,它能够将企业数据以统一的列格式整齐地汇总至其中。DataEase开源数据可视化分析工具可以与金山多维表格对接,方便企业更加快捷地以金山多维表格为数据源,制作出可以实时更…

【网络版本计算器的实现】

本章重点 理解应用层的作用, 初识HTTP协议理解传输层的作用, 深入理解TCP的各项特性和机制对整个TCP/IP协议有系统的理解对TCP/IP协议体系下的其他重要协议和技术有一定的了解学会使用一些分析网络问题的工具和方法 ⭐注意!! 注意!! 注意!! 本课是网络编程的理论基础.是一个服务…

Antd Vue项目引入TailwindCss之后出现svg icon下移,布局中的问题解决方案

目录 1. 现象: 2. 原因分析: 3. 解决方案: 写法一:扩展Preflight 写法二: 4. 禁用 Preflight 1. 现象: Antd Vue项目引入TailwindCss之后出现svg icon下移,不能对齐显示的情况&#xff0…

爬虫实训案例:中国大学排名

近一个月左右的时间学习爬虫,在用所积累的知识爬取了《中国大学排名》这个网站,爬取的内容虽然只是可见的文本,但对于初学者来说是一个很好的练习。在爬取的过程中,通过请求数据、解析内容、提取文本、存储数据等几个重要的内容入…

React-router 最佳实践

使用的是 BrowserRouter,Routes 和 Route,这是 react-router-dom v5 和 v6 都支持的 API。这种方式的优点是路由配置和应用的其它部分是紧密集成的,这使得路由配置更加直观和易于理解 // router/index.js import { BrowserRouter as Router,…

【Qt 学习笔记】Qt常用控件 | 布局管理器 | 网格布局Grid Layout

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt常用控件 | 布局管理器 | 网格布局Grid Layout 文章编号&#xff1a…

成品短视频APP源码搭建

在数字化时代,短视频已成为全球范围内的流行趋势,吸引了大量的用户和内容创作者。对于有志于进入短视频领域的企业和个人来说,成品短视频APP源码搭建提供了一条快速、高效的路径。本文将探讨成品短视频APP源码搭建的过程及其优势,…

Mac维护神器CleanMyMac X成为你的苹果电脑得力助手

在数字化时代,Mac电脑已成为众多用户的首选。然而,随着频繁的使用和数据量的日益增长,许多Mac用户面临着系统杂乱、存储空间不足以及隐私保护等问题。幸运的是,"CleanMyMac X"这款优化和清理工具应运而生,它…

[论文笔记]REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS

引言 今天带来一篇经典论文REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS的阅读笔记,论文中文意思是 在语言模型中协同推理和行动。 虽然大型语言模型(LLMs)在语言理解和互动决策任务中展现出强大的能力,但它们在推理(例如思维链提示)和…

【算法】栈算法——最小栈

题解:最小栈(栈算法) 目录 1.题目2.题解3.总结 1.题目 题目链接:LINK 这个题目题意说的有点绕,说白了让你在常数时间内检索到最小元素就是O(1)时间复杂度下找到栈中最小的元素。 2.题解 思路:这个栈可以内嵌套两个库栈来进行…

商品发布功能

文章目录 1.SPU和SKU介绍1.SPU2.SKU3.两者之间的关系 2.完成商品发布界面1.组件引入1.commoditylaunch.vue 引入到 src/views/modules/commodity下2.multiUpload.vue 引入到 src/components/upload/multiUpload.vue 2.创建菜单1.创建目录2.创建菜单,注意菜单路由要匹…

开源博客项目Blog .NET Core源码学习(25:App.Hosting项目结构分析-13)

本文学习并分析App.Hosting项目中后台管理页面的文章管理页面。   文章管理页面用于显示、检索、新建、编辑、删除文章数据,以便在前台页面的首页、文章专栏、文章详情页面显示文章数据。文章管理页面附带一新建及编辑页面,以支撑新建和编辑文章数据。…

交换机部分综合实验

实验要求 1.内网IP地址使用172.16.0.0/16 2.sw1和sW2之间互为备份; 3.VRRP/mstp/vlan/eth-trunk均使用; 4.所有pc均通过DHcP获取Ip地址; 5.ISP只配置IP地址; 6.所有电脑可以正常访问IsP路由器环回 实验拓扑 实验思路 1.给交换机创建vlan,并将接口划入vlan 2.在SW1和…

传输层 --- UDP

一、简述与回顾 传输层:负责数据能够从发送端传输接收端 在TCP/IP协议中,我们用"源IP","源端口号","目的IP","目的端口号",和"协议号"来表示一个通信。…

Android studio关闭自动更新

Windows下: 左上角file - setting - Appearance & Behavier - system setting - update - 取消勾选

golang通过go-aci适配神通数据库

1. go-aci简介 go-aci是神通数据库基于ACI(兼容Oracle的OCI)开发的go语言开发接口,因此运行时需要依赖ACI驱动和ACI库的头文件。支持各种数据类型的读写、支持参数绑定、支持游标范围等操作。 2. Linux部署步骤 2.1. Go安装: 版本:1.9以上…