关于前端:关于-ArrayBuffer

77次阅读

共计 3087 个字符,预计需要花费 8 分钟才能阅读完成。

ArrayBuffer 是什么

ArrayBuffer 对象用来示意通用的、固定长度的原始二进制数据缓冲区。

它是一个字节数组,通常在其余语言中称为“byte array”。

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

简略用法

const buffer = new ArrayBuffer(8);

console.log(buffer.byteLength); // 8

length 大于 Number.MAX_SAFE_INTEGER(>= 2 53)或为正数,则抛出一个 RangeError 异样。**

作用

从 XHR、File API、Canvas, WebGL 等等各种中央,读取了一大串字节流,如果用 JS 里的 Array 去存,又节约,又低效

于是为了配合这些新的 API 加强 JS 的二进制解决能力,就有了 ArrayBuffer

创立 ArrayBuffer 的时候, 就相当于申请了一块内存, 不能(也不不便)间接用它

所以也就有了 TypedArray, 比方 Uint32Array,Int16Array , Int8Array, Float32Array 等等等等

这些就是用来操作 TypedArray 的具体实现

TypeArray

一个类型化数组(TypedArray)对象形容了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。事实上,没有名为 TypedArray 的全局属性,也没有一个名为 TypedArray 的构造函数。相同,有许多不同的全局属性,它们的值是特定元素类型的类型化数组构造函数,如下所示

// 上面代码是语法格局,不能间接运行,// TypedArray 关键字须要替换为底部列出的构造函数。new TypedArray(); // ES2017 中新增
new TypedArray(length);
new TypedArray(typedArray);
new TypedArray(object);
new TypedArray(buffer [, byteOffset [, length]]);
// TypedArray 指的是以下的其中之一:Int8Array();
Uint8Array();
Uint8ClampedArray();
Int16Array();
Uint16Array();
Int32Array();
Uint32Array();
Float32Array();
Float64Array();
  • Unit8Array 指的是,把 ArrayBuffer 的每个 byte(8-bit) 当作一个独自的无符号整型数字 (0 – 255)
  • Unit16Array 示意为应用 16 bits (2 bytes) 示意一个无符号整型 (0 ~ 2^16-1) 的数的数组
  • Int8Array 示意应用 8 bits 示意一个有符号整型 (-128 ~ 127)
  • Float32Array 示意应用 32 bits 示意一个浮点数
  • Unit7ClampedArray 在 0 ~ 255 范畴内和 Unit8Array 是一样的,对超出范围的解决有所不同,和图像处理相干(个别像素范畴也是 0 ~ 255)

应用场景:

文件的转换:

arrayBuffer 能够转换为 Blob 对象:

 const blob = new Blob([arrayBuffer],{type:"xxx/xxx"});

Blob 转换为 arrayBuffer:


  const fileReader:FileReader = new FileReader();

  fileReader.addEventListener("load",(event)=>{
    const arrayBuffer = event.target.result;
    //...
  })

  fileReader.readAsArrayBuffer(file);

或者:

  const arrayBuffer = await file.arrayBuffer();

从 ajax 获取:

  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'xxxxx');

  xhr.responseType = 'arraybuffer';

  xhr.onload = function(e) {if (this.status == 200) {const arrayBuffer = xhr.response;}
  };

  xhr.send();

例子 1

音频的某一种播放办法

  const audioContext = new AudioContext();

  const buffer = await file.arrayBuffer();

  const auidoBuffer = await audioContext.decodeAudioData(buffer);

  const source = audioContext.createBufferSource();

  source.buffer = auidoBuffer;

  source.connect(audioContext.destination);
  source.start();

例子 2

读取二进制文件

// HTML 代码如下
// <input type="file" onchange="typefile(this.files[0])"></input>
function typefile(file) {
  // 文件结尾的四个字节,生成一个 Blob 对象
  let slice = file.slice(0, 4);
  let reader = new FileReader();
  // 读取这四个字节
  reader.readAsArrayBuffer(slice);
  reader.onload = function (e) {
    let buffer = reader.result;
    // 将这四个字节的内容,视作一个 32 位整数
    let view = new DataView(buffer);
    let magic = view.getUint32(0, false);
    // 依据文件的前四个字节,判断它的类型
    switch(magic) {
      case 0x89504E47: file.verified_type = 'image/png'; break;
      case 0x47494638: file.verified_type = 'image/gif'; break;
      case 0x25504446: file.verified_type = 'application/pdf'; break;
      case 0x504b0304: file.verified_type = 'application/zip'; break;
    }
    console.log(file.name, file.verified_type);
  };
}

总结

这里还有很多货色没讲, 比方 SharedArrayBuffers, 大小端问题等等, 想要深刻的话能够自行理解

在前端应用到 buffer 的场景的确十分少见, 但波及到比拟底层或者偏门一点点的时候就会看到他了, 这个时候也要求咱们要理解他, 比方文件, canvas, WebGL, WASM, EXCEL 解决

援用

  • https://developer.mozilla.org…
  • https://www.zhihu.com/questio…
  • https://javascript.info/array…
  • https://zhuanlan.zhihu.com/p/…
  • https://developer.mozilla.org…
  • https://zhuanlan.zhihu.com/p/…
  • https://zhuanlan.zhihu.com/p/…

正文完
 0