認識Js中的二進制數據

Blob

在項目中涉及到要對html原生的audio組件進行樣式複寫,所以須要從新實現audio的一些功能,好比下載。實現一個下載大體的思路是服務端返回一段音頻的二進制數據,客戶端將其存放在Blob中,再經過URL.createObjectURL將其轉換成blob url,最後動態建立a標籤,添加download屬性,模擬點擊事件來實現下載。代碼比較簡單,咱們重點來看看Blob是何方神聖。javascript

const saveExcelFile = (blob, filename) => {
    if (window.navigator.msSaveOrOpenBlob) {
      // iE下使用msSaveBlob進行導出
      navigator.msSaveBlob(blob, filename)
    } else {
      var href = window.URL.createObjectURL(blob)

      var save_link = document.createElementNS(
        'http://www.w3.org/1999/xhtml',
        'a'
      )
      save_link.href = href
      save_link.download = filename

      // 解決火狐兼容問題
      document.body.appendChild(save_link)

      var event = document.createEvent('MouseEvents')
      event.initMouseEvent(
        'click',
        true,
        false,
        window,
        0,
        0,
        0,
        0,
        0,
        false,
        false,
        false,
        false,
        0,
        null
      )
      save_link.dispatchEvent(event)

      document.body.removeChild(save_link)
      // 釋放blob url,可被GC回收
      window.URL.revokeObjectURL(href)
    }
}

根據MDN的介紹,咱們能夠知道Blob類型的對象是相似文件對象的二進制數據,它是immutable的,即數據不可變。而HTML5的File對象繼承於Blob對象,並在其基礎上作了些擴展,從而具有了在操做系統上操做文件的能力。咱們能夠利用Blob去作一些下載文件、分片上傳等功能。熟悉ES6的小夥伴應該知道,ES6中有一個ArrayBuffer對象,也是用來存儲二進制數據的,那它和Blob有什麼區別呢?html

ArrayBuffer

根據一些資料,ArrayBuffer設計的目的與WebGL項目有關,爲了知足JS與顯卡或聲卡等操做系統原生接口大量的、實時的數據交換。傳統的文本格式是傳遞一個32位的整數,這致使JS與原生接口須要頻繁的轉換數據格式,效率較低,所以設計了ArrayBuffer用於存儲、操做二進制數據。
ArrayBuffer並非真正的Array,而是個類數組對象。咱們經過new ArrayBuffer(length)建立的ArrayBuffer的實例,僅僅表明開闢了一段連續的內存空間,length表明內存所佔的字節大小。若須要對內存中的字節進行操做,則須要建立「視圖」。視圖分爲兩種:TypedArray和DataView,用於以指定的格式來讀寫二進制的數據。它們的區別在於:java

  • TypedArray以指定的格式讀寫內存,例如:const v1 = new Int32Array(buffer)就是以32位有符號整型來建立視圖,此時經過v1[0]去讀或是去寫都是以該格式進行的
  • 如果想以不一樣數據格式去讀取內存的話,須要使用DataView。當咱們執行const dv = new DataView(buffer)後,能夠經過相似dv.getUint8(0)這樣的方式,以8位無符號整型讀取第一個字節;或是以dv.setInt32(1, 25)這種方式,在第二個字節寫入值爲25的32位有符號整型數據

注意:對於同一段內存建立的視圖都是共享該內存的,在一個視圖上進行的操做會影響另外一個視圖的讀寫。具體的可參考阮老師的教程es6

區別

  • ArrayBuffer能夠對字節進行讀寫,而Blob是immutable的
  • ArrayBuffer存儲在內存當中,Blob能夠存儲在磁盤或者內存中。例如文件,咱們平時是存在磁盤中的。而像咱們上面下載的例子中,咱們的blob是在內存中的,所以在createObjectURL以後須要手動調用revokeObjectURL解除對內存的引用,使得blob能夠被GC回收,釋放內存。
  • ArrayBuffer能夠經過「視圖」來進行讀寫,而Blob能夠經過FileReader去讀,可是不能寫
  • Blob和ArrayBuffer能夠互相轉換。Blob轉ArrayBuffer能夠經過:
    javascript const reader = new FileReader() reader.onload = function() { console.log(reader.result) } reader.readAsArrayBuffer(blob)
    ArrayBuffer轉Blob能夠經過:
    javascript const blob = new Blob([ArrayBuffer]) 所以,當咱們須要對字節進行操做的時候,咱們應該選用ArrayBuffer,不然,咱們用Blob會更加容易。
相關文章
相關標籤/搜索