javascript處理二進制之ArrayBuffer

最先javascript是不能處理二進制的,若是非要處理,只能用charCodeAt逐個地將字符串轉成Unicode 編碼的二進制數據。直到ECMAScript 5引入了blob,才使JS能真正能夠處理二進制數據。javascript

File API

blob又有一些衍生對象:File對象、FileList對象、URL對象、FileReader對象。java

好比:canvas

document.querySelector('input[name=picture]').onchange = function (e) {
    console.log(e.target.files[0]);
}
複製代碼

AJAX

好久以前,AJAX只能獲取文本數據,XMLHttpRequest第二版容許服務器返回二進制數據。這時分紅兩種狀況。若是明確知道返回的二進制數據類型,能夠把返回類型(responseType)設爲arraybuffer;若是不知道,就設爲blob:數組

et xhr = new XMLHttpRequest();
xhr.open('GET', someUrl);
xhr.responseType = 'arraybuffer';

xhr.onload = function () {
  let arrayBuffer = xhr.response;
  // ···
};

xhr.send();
複製代碼

Canvas

Canvas元素輸出的二進制元素是 TypedArray。bash

const ctx = canvas.getContext('2d');

const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const uint8ClampedArray = imageData.data;
複製代碼

爲了配合以上的API,讓JS更加好地處理二進制,ES6 將早就存在的ArrayBuffer對象、TypedArray視圖和DataView視圖歸入了 ECMAScript 規格。服務器

ArrayBuffer表明了一段存儲二進制數據的內存,是它的抽象層,好比 new ArrayBuffer(1024) ,咱們就開闢了一段一個字節的內存。ui

可是你不能直接讀寫ArrayBuffer,而要用標準中的另外兩種視圖TypedArray或DataView。就想C語言中你不能直接處理內存,而須要將其轉化成指針。this

好比,若是咱們使用TypedArray以下。ArrayBuffer一共有九種,且其數組成員必須是一個類型。咱們先建立了一塊有32個字節的內存區域buf,而後建立了一個指向buf的16位視圖,開始於字節2,長度爲2。第三個參數就是視圖包含的數據個數,默認直到本段內存區域結束。編碼

const buf = new ArrayBuffer(32);

const int = new Int16Array(buf, 2, 2);
複製代碼

咱們也能夠不經過ArrayBuffer,直接用TypedArray開闢一段內存。好比下面,生成了一個有八個成員的數組,每一個成員8個字節,一共64個字節spa

const f64a = new Float64Array(8);
複製代碼

每一個TypeArray實例都有一個BYTES_PER_ELEMENT屬性表明字節數,如同ArrayBuffer的byteLength屬性。length屬性依然是數組的長度,普通數組的方法和屬性,TypedArray 數組也徹底適用。

TypedArray.prototype.slice(start=0, end=this.length)
TypedArray.prototype.copyWithin(target, start[, end = this.length]) 等
複製代碼

ArrayBuffer 自己只是一個 0 和 1 存放在一行裏面的集合,它自己並不負責怎麼分配。

(圖片來源 —— A cartoon intro to ArrayBuffers and SharedArrayBuffers

用int8來存放:

用Unit16來存放:

咱們從Int8數組裏獲取了元素 0下標的數據 和 1下標的數據,和在 Uint16數組 中0下標的數據是不一樣的,儘管他們都是同一段內存,是徹底同樣的二進制字節:

(圖片來源 —— A cartoon intro to ArrayBuffers and SharedArrayBuffers

另外,咱們會經常使用讓字符串轉換成Buffer,遍歷字符串,並在建立的數組中存放對應字符的unicode編碼:

const buf = new ArrayBuffer(str.length * 2); // 每一個字符佔用2個字節
  const bufView = new Uint16Array(buf);    // 用js默認的16位無符號整數爲單位
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
複製代碼
相關文章
相關標籤/搜索