zoukankan      html  css  js  c++  java
  • 3-ArrayBuffer与类型化数组

    写在前面

    这是关于JS二进制操作的第三篇博客
    此前从宏观角度介绍了如何通过JS创建一个二进制对象,并介绍了如何将本地二进制内容读取至内存。本篇将介绍如何在内存中操作二进制数据。

    JS与二进制数据

    现代计算机中操作二进制数据的基本单位是字节(byte),故二进制数据一般以字节数组的形式存在于程序中。如:Java中的InputStream于OutputStream类,允许通过指定大小的字节数组(如:byte[] bytes = new byte[1024])对文件进行读写。
    然而回到JS,其设计之初也没有想过要处理二进制,故对于字节的概念并不清晰。再加上JS对数据类型的弱化,即使要表示字节数组,也只能通过普通数组的方式表示。
    HTML5的建立对前端而言是颠覆性的,一方面基于XHR2, 使上传下载二进制内容成为可能;另一方面,WebGL/Canvas等新技术需要JS与显卡之间进行大量的、实时的数据交换,而其数据通信的形式必须是二进制。这样,JS操作二进制成为了必然。
    在JS中,可以通过ArrayBuffer和类型化数组(Typed Array)在内存中对二进制数据进行操作。

    ArrayBuffer

    ArrayBuffer是一段连续的长度固定的字节序列,如:通过实例化ArrayBuffer对象在内存中创建一段二进制存储空间(或叫二进制缓冲区),

    // 创建一段字节长度为8的内存空间
    var buffer = new ArrayBuffer(8);
    // 获取字节长度
    console.log(buffer.byteLength); // 8
    

    由于是连续的内存空间,故在其上进行的读写操作都会比普通JS Array快很多。
    但需要说明的是:ArrayBuffer只是存储数据的区域,无法进行读写。若想进行访问,需要借助类型化数组(Typed Array)
    故可以理解为:类型化数组是访问ArrayBuffer中数据的接口

    类型化数组

    类型化数组(或称视图view)是读写ArrayBuffer中数据的接口,JS可以通过8种不同的接口创建类型化数组,分别为:

    名称描述字节长度
    Int8Array 8位有符号整数 1
    Uint8Array 8位无符号整数 1
    Int16Array 16位有符号整数 2
    Uint16Array 16位无符号整数 2
    Int32Array 32位有符号整数 4
    Uint32Array 32位无符号整数 4
    Float32Array 32位浮点数 4
    Float64Array 64位浮点数 8

    通过类型化数组可以对ArrayBuffer中的数据进行读写,一段ArrayBuffer上可以重叠多个类型化数组。

    // 创建一段12字节的ArrayBuffer
    var b = new ArrayBuffer(12);
    // 在b上创建一个视图v1,视图中每个元素类型为Uint8(占1字节),开始于字节索引0,结束于ArrayBuffer结尾
    var v1 = new Uint8Array(b);
    // 在b上创建一个视图v2,视图中每个元素类型为Uint32(占4字节),开始于字节索引4,结束于ArrayBuffer结尾
    var v2 = new Uint32Array(b,4);
    // 在b上创建一个视图v3,视图中每个元素类型为Uint16(占2字节),开始于字节索引2,视图长度为2,结束于字节索引5
    var v3 = new Uint16Array(b,2,2);
    

    下面画图说明存储方式:

    如图可见,一段ArrayBuffer上重叠了三个视图,可以通过三种方式访问ArrayBuffer中的数据
    此时做如下测试:
    1、通过v1向b中写入数据
    2、通过v1、v2、v3从b中读取数据

    下面简单说明下各输出:
    首先通过v1为每个元素赋值为十进制1,则ArrayBuffer中每个元素存储的二进制为00000001
    通过v2读取,v2[0]和v2[1]中读取出的二进制均为00000001000000010000000100000001,转换为十进制即为16843009
    通过v3读取,v3[0]和v3[1]中读取出的二进制均为0000000100000001,转换为十进制即为257
    由此我们可以归纳出ArrayBuffer与类型化数组间的关系:

    • ArrayBuffer存储二进制数据,但只有通过类型化数组才能进行二进制数据的读写
    • 一段ArrayBuffer上可以重叠多个不同的类型化数组,不同类型化数组影响对ArrayBuffer中数据的读写方式

    总结

    本篇主要介绍如何对内存中的二进制内容进行读写,并重点介绍了ArrayBuffer及类型化数组的关系。写这篇的目的也是在于解释ArrayBuffer中二进制数据存在的形式,但往往我们操作本地文件时,并不需要关心二进制数据内容是如何排列的,故此处不讨论字节序或对齐等问题,以后有机会可能会结合Canvas进行说明。

    参考资料

    MDN_ArrayBuffer
    MDN_TypedArray

  • 相关阅读:
    linux 命令——19 find (转)
    linux 命令——18 locate (转)
    linux 命令——17 whereis(转)
    linux 命令——16 which(转)
    linux 命令——15 tail (转)
    linux 命令——14 head (转)
    Java for LeetCode 038 Count and Say
    Java for LeetCode 037 Sudoku Solver
    Java for LeetCode 036 Valid Sudoku
    Java for LeetCode 035 Search Insert Position
  • 原文地址:https://www.cnblogs.com/haoqiyouyu/p/14388907.html
Copyright © 2011-2022 走看看