js 的 ArrayBuffer 和 dataView
一个十六进制代表4位,0xF = 1111,0xFF = 1111 1111,八位是1字节,所以通常用两个16进制代表1字节。
假如我申请一个8字节的内存空间,然后初始化为0,大概就这样: 00 00 00 00 00 00 00 00
什么是类型,BYTE(1字节),WORD(2字节),DWORD(4字节),QWORD(8字节) 这种类型是在读/写内存地址时的偏移字节数,当然也可以手动偏移
arrayBuffer 中的Int8是8位也就是BYTE类型,对它进行读写的偏移值是1字节
arrayBuffer 中的Int16是16位也就是WORD类型,对它进行读写的偏移值是2字节
假如我申请一块4字节大小的空间,并按4字节大小进行读取:
let buffer = new ArrayBuffer(4)
let view = new Uint32Array(buffer);
view[0] = 0xA
如果这时候打印buffe将会看到如下结构:
ArrayBuffer(4) {}
[[Int8Array]]: Int8Array(4) [10, 0, 0, 0]
[[Int16Array]]: Int16Array(2) [10, 0]
[[Int32Array]]: Int32Array [10]
[[Uint8Array]]: Uint8Array(4) [10, 0, 0, 0]
byteLength: 4
Int32Array显示为0x0000 000A,Int8Array显示为0x0A00 0000,为什么Int8Array显示为0x0A00 0000而不是0x0000 000A。
这可能是因为我的计算机是以小端模式存储数据,什么是小端模式:数据低位在地址低位,数据高位在地址高位
假如我在0x100-0x200的虚拟内存空间中申请一块4字节内存,返回的内存地址(在有“指针”的计算机语言中也叫做“指针”)为0x180,
这时将0x0000 000A存进去,数据的高位时在左边,低位在右边0A这里, 在0x180地址存就像:
0x17D 0A
0x17E 00
0x17F 00
0x180 00
如果这个时候再用Int8Array操作一下这段内存数据:
let view2 = new Int8Array(buffer)
view2[1] = 0x01 // 0A 01 00 00
这时的内存数据为 0A 01 00 00,也就是0x010A十进制的266,这时再用view查看4字节数据也是266
ArrayBuffer 所有的数据都是10进制显示的
ArrayBuffer 不能直接操作,而是要通过类型数组对象或 DataView 对象来操作, 它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
上面是基础计算机内存知识,下面时ArrayBuffer api知识
let l = console.log
// 申请一个大小为8字节的内存空间,初始化为0
let buffer = new ArrayBuffer(8)
l(buffer.byteLength) // 单位为字节
// 查看是否是ArrayBuffer
l( ArrayBuffer.isView(new DataView(buffer)) )
// 使用一个 Int32Array 来引用
// 32 代表32位,4字节。buffer申请的空间只有8字节,只能存两个int32的值
let view = new Int32Array(buffer)
l(view)
// 4字节最大就只能存 0x00000000 - 0xFFFFFFFF
view[0] = 0xFFFF
view[1] = 0xFFFE
byteLength 和 length
byteLength不会变化(字节大小), length会更具 类型数组对象 发生变化
let l = console.log
let buffer = new ArrayBuffer(8)
let int8 = new Int8Array(buffer)
l(int8.byteLength, int8.length) // 8, 8
let uint8 = new Uint8Array(buffer)
l(uint8.byteLength, uint8.length) // 8, 8
let uint8clamped = new Uint8ClampedArray(buffer)
l(uint8clamped.byteLength, uint8clamped.length)// 8, 8
let int16 = new Int16Array(buffer)
l(int16.byteLength, int16.length) // 8, 4 小两倍
let uint16 = new Uint16Array(buffer)
l(uint16.byteLength, uint16.length)// 8, 4
let int32 = new Int32Array(buffer)
l(int32.byteLength, int32.length)// 8, 2 小四倍
let uint32 = new Uint32Array(buffer)
l(uint32.byteLength, uint32.length)// 8, 2
类型数组对象 文档
new TypedArray(length); 常用
> 当传入length参数时,一个内部数组缓冲区被创建.
> 该缓存区的大小是传入的length乘以数组中每个元素的字节数,每个元素的值都为0.
> (译者注:每个元素的字节数是由具体的构造函数决定的,比如Int16Array的每个元素的字节数为2,Int32Array的每个元素的字节数为4)
new TypedArray(typedArray); 常用
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]); 常用
以下皆是 TypedArray() :
Unsigned Int 无符号整数
Int8Array();
Uint8Array();
Uint8ClampedArray();
Int16Array();
Uint16Array();
Int32Array();
Uint32Array();
Float32Array();
Float64Array();
let l = console.log
let buffer = new ArrayBuffer(8)
let a = new Int8Array(buffer)
for (let i = 0; i < buffer.byteLength; i++) {
a[i] = i
}
l(a) // Int8Array(8) [0, 1, 2, 3, 4, 5, 6, 7]
l(a[a.byteLength - 1]) // 使用下标获取值
l(a.length) // 实际长度
l(new Int8Array(buffer, 2)) // 偏移两位 Int8Array(6) [2, 3, 4, 5, 6, 7]
DataView 文档
DataView 视图是一个可以从 ArrayBuffer 对象中读写多种数值类型的底层接口,在读写时不用考虑平台字节序问题(默认大端法)
如果由偏移(byteOffset)和字节长度(byteLength)计算得到的结束位置超出了 buffer 的长度,抛出此异常。
let l = console.log
// new DataView(buffer [, byteOffset [, byteLength]])
let buffer = new ArrayBuffer(8)
let view = new DataView(buffer, 0)
// setInt16(byteOffset: number, value: number, littleEndian?: boolean)
// 如果littleEndian为true则按小端法存储,否则就按大端法存储, 默认是大端
view.setInt16(0, 14)
l(view)
// getInt16(byteOffset: number, littleEndian?: boolean)
l(view.getInt16(0))// 14
l(view.getInt8(0))// 0
l(view.getInt32(0))// 917504
// 只读属性,实例的时候已固化
l(view.buffer)
l(view.byteLength)
l(view.byteOffset)
字节序
let l = console.log
var littleEndian = (function () {
var buffer = new ArrayBuffer(2);
// 小端字节序和大端字节序: https://blog.csdn.net/qq_33724710/article/details/51056542
new DataView(buffer).setInt16(0, 256, true /* 设置值时使用小端字节序 */ );
// Int16Array 使用系统字节序,由此可以判断系统是否是小端字节序
l(buffer)
let int16 = new Int16Array(buffer)
l(int16)
return int16[0] === 256;
})();
console.log(littleEndian); // true or false
buffer库,和nodejs的Buffer基本一样的api
<script src="https://bundle.run/buffer@5.6.0"></script>
<script>
const { Buffer } = buffer;
const buf = Buffer.alloc(4);
buf.writeInt32LE(0x0A);
console.log(buf);
console.log(buf.readInt32LE().toString(16) );
</script>
js 的 ArrayBuffer 和 dataView的更多相关文章
- Buffer、ArrayBuffer、DataView互转(node.js)
1.Buffer转ArrayBuffer // 实例一 const buf = Buffer.from("this is a test"); console.log(buf); c ...
- 24.ArrayBuffer
ArrayBuffer ArrayBuffer ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立 ...
- ES6的新特性(23)——ArrayBuffer
ArrayBuffer ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立的规格(2011 年 2 ...
- 基于layui+cropper.js实现上传图片的裁剪功能
最近因项目需求,需要在上传图片的时候先对图片裁剪,然后在上传,所以就有了本文的出现. 开始正文之前,要提一下这个图片的裁剪:图片的裁剪,有前端裁剪,也可以后端裁剪 前端的裁剪我知道的可以分为这么两种: ...
- ArrayBuffer
ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立的规格(2011 年 2 月发布),ES6 将它 ...
- ES6学习笔记(二十二)ArrayBuffer
ArrayBuffer ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.它们都是以数组的语法处理二进制数据,所以统称为二进 ...
- File、Blob、ArrayBuffer等文件类的对象有什么区别和联系
前言 在前端中处理文件时会经常遇到File.Blob.ArrayBuffer以及相关的处理方法或方式如FileReader.FormData等等这些名词,对于这些常见而又不常见的名词,我相信大多数人对 ...
- js获取图片的EXIF,解决图片旋转问题
相信大家在做项目的时候会遇到在canvas里加入图片时,图片发生90°,180°的旋转.当时的你肯定时懵逼的,为毛. 其实这就是图片的EXIF搞的鬼. 什么是EXIF 简单来说,Exif 信息就是由数 ...
- Practical Node.js摘录(2018版)第1,2章。
大神的node书,免费 视频:https://node.university/courses/short-lectures/lectures/3949510 另一本书:全栈JavaScript,学习b ...
随机推荐
- .Vue-router跳转和location.href有什么区别
使用location.href='/url'来跳转,简单方便,但是刷新了页面:使用history.pushState('/url'),无刷新页面,静态跳转:引进router,然后使用router.pu ...
- 挖掘隐藏在源码中的Vue技巧!
前言 最近关于Vue的技巧文章大热,我自己也写过一篇(vue开发中的"骚操作"),但这篇文章的技巧是能在Vue的文档中找到蛛丝马迹的,而有些文章说的技巧在Vue文档中根本找不到踪迹 ...
- LOJ10067
LOJ10067 构造完全图 给你一棵树 T,找出 T 能扩展出的边权和最小的完全图 G. 第一行 N 表示树 T 的点数: 保证输入数据构成一棵树. 输出仅一个数,表示最小的完全图 G 的边权和. ...
- 2020最新idea永久激活教程
注:以下为 idea 最新版本 2020.3.2 的永久激活教程,请按照如下步骤安装激活 (webstorm.pycharm 激活方法相同). 步骤一.下载安装包 去到 idea 官网 https:/ ...
- 高性能缓存 Caffeine 原理及实战
一.简介 Caffeine 是基于Java 8 开发的.提供了近乎最佳命中率的高性能本地缓存组件,Spring5 开始不再支持 Guava Cache,改为使用 Caffeine. 下面是 Caffe ...
- vulnhub靶场之AI-WEB1.0渗透记录
在本机电脑上自行搭建了一个练手的靶场,下面是记录渗透过程 目录 一.确认靶机ip 二.端口&目录扫描 三.查看敏感目录 四.sql注入 五.get shell 六.系统提权 确认靶机ip ka ...
- python--基础1(pip,虚拟环境、python编写规范)
python简介 1.Python是一种解释型脚本语言; 2.Python在设计上坚持了清晰划一的风格,这使得Python成为一门易读.易维护,并且被大量用户所欢迎的.用途广泛的语言; 3.pytho ...
- 通过模拟数据,使用js在前端实现模糊查询下拉框功能实例教程
所谓模糊查询就是通过关键字在数据中匹配到包含关键字的数据,而得出的查询结果.本实例教程讲解在前端文本框输入关键字,显示匹配的数据列表功能. 首先得准备一个文本框和显示数据列表的div元素,html代码 ...
- Flink-v1.12官方网站翻译-P005-Learn Flink: Hands-on Training
学习Flink:实践培训 本次培训的目标和范围 本培训介绍了Apache Flink,包括足够的内容让你开始编写可扩展的流式ETL,分析和事件驱动的应用程序,同时省略了很多(最终重要的)细节.本书的重 ...
- shell脚本的使用该熟练起来了,你说呢?(篇一)
作者:良知犹存 转载授权以及围观:欢迎添加微信公众号:羽林君