一个十六进制代表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字节大小进行读取:

  1. let buffer = new ArrayBuffer(4)
  2. let view = new Uint32Array(buffer);
  3. view[0] = 0xA

如果这时候打印buffe将会看到如下结构:

  1. ArrayBuffer(4) {}
  2. [[Int8Array]]: Int8Array(4) [10, 0, 0, 0]
  3. [[Int16Array]]: Int16Array(2) [10, 0]
  4. [[Int32Array]]: Int32Array [10]
  5. [[Uint8Array]]: Uint8Array(4) [10, 0, 0, 0]
  6. byteLength: 4

Int32Array显示为0x0000 000A,Int8Array显示为0x0A00 0000,为什么Int8Array显示为0x0A00 0000而不是0x0000 000A。

这可能是因为我的计算机是以小端模式存储数据,什么是小端模式:数据低位在地址低位,数据高位在地址高位

假如我在0x100-0x200的虚拟内存空间中申请一块4字节内存,返回的内存地址(在有“指针”的计算机语言中也叫做“指针”)为0x180,

这时将0x0000 000A存进去,数据的高位时在左边,低位在右边0A这里, 在0x180地址存就像:

  1. 0x17D 0A
  2. 0x17E 00
  3. 0x17F 00
  4. 0x180 00

如果这个时候再用Int8Array操作一下这段内存数据:

  1. let view2 = new Int8Array(buffer)
  2. view2[1] = 0x01 // 0A 01 00 00

这时的内存数据为 0A 01 00 00,也就是0x010A十进制的266,这时再用view查看4字节数据也是266

ArrayBuffer 所有的数据都是10进制显示的

ArrayBuffer 不能直接操作,而是要通过类型数组对象或 DataView 对象来操作, 它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

上面是基础计算机内存知识,下面时ArrayBuffer api知识

  1. let l = console.log
  2. // 申请一个大小为8字节的内存空间,初始化为0
  3. let buffer = new ArrayBuffer(8)
  4. l(buffer.byteLength) // 单位为字节
  5. // 查看是否是ArrayBuffer
  6. l( ArrayBuffer.isView(new DataView(buffer)) )
  7. // 使用一个 Int32Array 来引用
  8. // 32 代表32位,4字节。buffer申请的空间只有8字节,只能存两个int32的值
  9. let view = new Int32Array(buffer)
  10. l(view)
  11. // 4字节最大就只能存 0x00000000 - 0xFFFFFFFF
  12. view[0] = 0xFFFF
  13. view[1] = 0xFFFE

byteLength 和 length

byteLength不会变化(字节大小), length会更具 类型数组对象 发生变化

  1. let l = console.log
  2. let buffer = new ArrayBuffer(8)
  3. let int8 = new Int8Array(buffer)
  4. l(int8.byteLength, int8.length) // 8, 8
  5. let uint8 = new Uint8Array(buffer)
  6. l(uint8.byteLength, uint8.length) // 8, 8
  7. let uint8clamped = new Uint8ClampedArray(buffer)
  8. l(uint8clamped.byteLength, uint8clamped.length)// 8, 8
  9. let int16 = new Int16Array(buffer)
  10. l(int16.byteLength, int16.length) // 8, 4 小两倍
  11. let uint16 = new Uint16Array(buffer)
  12. l(uint16.byteLength, uint16.length)// 8, 4
  13. let int32 = new Int32Array(buffer)
  14. l(int32.byteLength, int32.length)// 8, 2 小四倍
  15. let uint32 = new Uint32Array(buffer)
  16. l(uint32.byteLength, uint32.length)// 8, 2

类型数组对象 文档

  1. new TypedArray(length); 常用
  2. > 当传入length参数时,一个内部数组缓冲区被创建.
  3. > 该缓存区的大小是传入的length乘以数组中每个元素的字节数,每个元素的值都为0.
  4. > (译者注:每个元素的字节数是由具体的构造函数决定的,比如Int16Array的每个元素的字节数为2,Int32Array的每个元素的字节数为4)
  5. new TypedArray(typedArray); 常用
  6. new TypedArray(object);
  7. new TypedArray(buffer [, byteOffset [, length]]); 常用
  8. 以下皆是 TypedArray() :
  9. Unsigned Int 无符号整数
  10. Int8Array();
  11. Uint8Array();
  12. Uint8ClampedArray();
  13. Int16Array();
  14. Uint16Array();
  15. Int32Array();
  16. Uint32Array();
  17. Float32Array();
  18. Float64Array();
  19. let l = console.log
  20. let buffer = new ArrayBuffer(8)
  21. let a = new Int8Array(buffer)
  22. for (let i = 0; i < buffer.byteLength; i++) {
  23. a[i] = i
  24. }
  25. l(a) // Int8Array(8) [0, 1, 2, 3, 4, 5, 6, 7]
  26. l(a[a.byteLength - 1]) // 使用下标获取值
  27. l(a.length) // 实际长度
  28. l(new Int8Array(buffer, 2)) // 偏移两位 Int8Array(6) [2, 3, 4, 5, 6, 7]

DataView 文档

DataView 视图是一个可以从 ArrayBuffer 对象中读写多种数值类型的底层接口,在读写时不用考虑平台字节序问题(默认大端法)

如果由偏移(byteOffset)和字节长度(byteLength)计算得到的结束位置超出了 buffer 的长度,抛出此异常。

  1. let l = console.log
  2. // new DataView(buffer [, byteOffset [, byteLength]])
  3. let buffer = new ArrayBuffer(8)
  4. let view = new DataView(buffer, 0)
  5. // setInt16(byteOffset: number, value: number, littleEndian?: boolean)
  6. // 如果littleEndian为true则按小端法存储,否则就按大端法存储, 默认是大端
  7. view.setInt16(0, 14)
  8. l(view)
  9. // getInt16(byteOffset: number, littleEndian?: boolean)
  10. l(view.getInt16(0))// 14
  11. l(view.getInt8(0))// 0
  12. l(view.getInt32(0))// 917504
  13. // 只读属性,实例的时候已固化
  14. l(view.buffer)
  15. l(view.byteLength)
  16. l(view.byteOffset)

字节序

  1. let l = console.log
  2. var littleEndian = (function () {
  3. var buffer = new ArrayBuffer(2);
  4. // 小端字节序和大端字节序: https://blog.csdn.net/qq_33724710/article/details/51056542
  5. new DataView(buffer).setInt16(0, 256, true /* 设置值时使用小端字节序 */ );
  6. // Int16Array 使用系统字节序,由此可以判断系统是否是小端字节序
  7. l(buffer)
  8. let int16 = new Int16Array(buffer)
  9. l(int16)
  10. return int16[0] === 256;
  11. })();
  12. console.log(littleEndian); // true or false

buffer库,和nodejs的Buffer基本一样的api

  1. <script src="https://bundle.run/buffer@5.6.0"></script>
  2. <script>
  3. const { Buffer } = buffer;
  4. const buf = Buffer.alloc(4);
  5. buf.writeInt32LE(0x0A);
  6. console.log(buf);
  7. console.log(buf.readInt32LE().toString(16) );
  8. </script>

js 的 ArrayBuffer 和 dataView的更多相关文章

  1. Buffer、ArrayBuffer、DataView互转(node.js)

    1.Buffer转ArrayBuffer // 实例一 const buf = Buffer.from("this is a test"); console.log(buf); c ...

  2. 24.ArrayBuffer

    ArrayBuffer ArrayBuffer ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立 ...

  3. ES6的新特性(23)——ArrayBuffer

    ArrayBuffer ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立的规格(2011 年 2 ...

  4. 基于layui+cropper.js实现上传图片的裁剪功能

    最近因项目需求,需要在上传图片的时候先对图片裁剪,然后在上传,所以就有了本文的出现. 开始正文之前,要提一下这个图片的裁剪:图片的裁剪,有前端裁剪,也可以后端裁剪 前端的裁剪我知道的可以分为这么两种: ...

  5. ArrayBuffer

    ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.这些对象早就存在,属于独立的规格(2011 年 2 月发布),ES6 将它 ...

  6. ES6学习笔记(二十二)ArrayBuffer

    ArrayBuffer ArrayBuffer对象.TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口.它们都是以数组的语法处理二进制数据,所以统称为二进 ...

  7. File、Blob、ArrayBuffer等文件类的对象有什么区别和联系

    前言 在前端中处理文件时会经常遇到File.Blob.ArrayBuffer以及相关的处理方法或方式如FileReader.FormData等等这些名词,对于这些常见而又不常见的名词,我相信大多数人对 ...

  8. js获取图片的EXIF,解决图片旋转问题

    相信大家在做项目的时候会遇到在canvas里加入图片时,图片发生90°,180°的旋转.当时的你肯定时懵逼的,为毛. 其实这就是图片的EXIF搞的鬼. 什么是EXIF 简单来说,Exif 信息就是由数 ...

  9. Practical Node.js摘录(2018版)第1,2章。

    大神的node书,免费 视频:https://node.university/courses/short-lectures/lectures/3949510 另一本书:全栈JavaScript,学习b ...

随机推荐

  1. REST以及RESTful

    java作为一门后端语言,其厉害之处在于web,大家比较熟知的各种网络应用,java都能做,那么在这个移动优先的时代,如何继续发挥java的强大呢.通常是让java作为一个app的服务端,为app客户 ...

  2. 项目总结—校园办公管理系统(SSM框架搭建)

    文章目录 CSDN下载地址:校园管理系统 GIT下载地址:校园管理系统 学以致用,学习完SSM框架之后,独立完成一个小院办公管理系统,熟悉框架的开发流程,熟悉项目的开发流程,完成一个简单的校园办公管理 ...

  3. Java8中流的性能

    流(Stream)是Java8为了实现最佳性能而引入的一个全新的概念.在过去的几年中,随着硬件的持续发展,编程方式已经发生了巨大的改变,程序的性能也随着并行处理.实时.云和其他一些编程方法的出现而得到 ...

  4. WLAN参数释义及优化建议

    1.AP覆盖范围或天线角度 1)参数释义 AP覆盖范围或天线角度直接影响到了终端连接到WLAN的信号强度. 2)优化建议 在设备的工程安装过程中,合理选择AP的位置,合理调整AP的覆盖方向或外置天线的 ...

  5. 19.损坏磁盘阵列及修复&磁盘阵列+备份盘

    1.在确认有一块物理硬盘设备出现损坏而不能继续正常使用后,应该使用mdadm 命令将其移除,然后查看RAID 磁盘阵列的状态,可以发现状态已经改变. [root@Centos ~]# mdadm /d ...

  6. Spring MVC 处理一个请求的流程分析

    Spring MVC是Spring系列框架中使用频率最高的部分.不管是Spring Boot还是传统的Spring项目,只要是Web项目都会使用到Spring MVC部分.因此程序员一定要熟练掌握MV ...

  7. 【论文研读】Sabir, Ekraam, et al. "Recurrent convolutional strategies for face manipulation detection in videos."&#160;Interfaces (GUI)&#160;3.1 (2019).

    #摘要 错误信息通过合成逼真的图像和视频进行传播这一严重问题,需要鲁棒的篡改检测方法来应对.尽管在检测静止图像上的面部篡改方面已付出了巨大的努力,但人们对于通过利用视频流中存在的时序信息,对视频中被篡 ...

  8. SpringMVC学习笔记2

    一.日期赋值 目标:在springMVC中日期赋值兼容性更广泛 不能直接处理,必须使用转换器1.定义转换器,实现接口Converter<From,To> package com.zy.co ...

  9. 阅读笔记:ImageNet Classification with Deep Convolutional Neural Networks

    概要: 本文中的Alexnet神经网络在LSVRC-2010图像分类比赛中得到了第一名和第五名,将120万高分辨率的图像分到1000不同的类别中,分类结果比以往的神经网络的分类都要好.为了训练更快,使 ...

  10. 2019HDU多校 Round6

    Solved:2 02 Nonsense Time (LIS) 题意:给定一个全排列 最开始为空的 每秒中一个位置上的数出现 求每秒的LIS 题解:题解说 考虑时光倒流 倒着消掉 因为数据随机 所以期 ...