簡體   English   中英

為什么Array的Blob小於Uint8Array的Blob?

[英]Why is Blob of Array smaller than Blob of Uint8Array?

我使用FileReader.readAsArrayBuffer讀取文件,然后執行以下操作:

  var compressedData = pako.gzip(new Uint8Array(this.result));
  var blob1 = new Blob([compressedData]); // size = 1455338 bytes
  var blob2 = new Blob(compressedData);   // size = 3761329 bytes

舉個例子:如果結果有4194304個字節,壓縮后它的大小為1455338個字節。 但由於某種原因,Uint8Array需要包裝在一個數組中。 為什么是這樣?

參看 BLOB構造函數的文檔:

https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob

[第一個參數]是一個ArrayBuffer,ArrayBufferView,Blob,DOMString對象的數組,或任何這些對象的混合,將放在Blob中。 DOMStrings編碼為UTF-8。

我不確定它是如何工作的,但基本上構造函數需要一些它將打包到BLOB中的東西。 因此,在第一種情況下,您正在構建單個部件的BLOB(即您的ArrayBuffer),而在第二種情況下,您將從1455338個部件(即每個字節分別)構建它。

由於文檔說BLOB部分只能是數組或字符串,它可能最終將ArrayBuffer中的每個字節值轉換為UTF-8字符串,這意味着它不是每個數字使用1個字節,而是每個十進制數使用1個字節(兩個結果大小的比率似乎支持這一點,因為單字節值是1-3位長,而較大的BLOB大小是較小的大小的2.5倍)。 這不僅浪費,我很確定它也會使您的ZIP無法使用。

所以,底線是,第一個版本是正確的方法。

不幸的是,MDN文章在這里幾乎是錯誤的,充其量是誤導性的。

從規格

可以使用以下參數調用Blob()構造函數:

  • 一個blobParts序列,它以任意順序接受任意數量的以下類型的元素:

    • BufferSource元素。

    • Blob元素。

    • USVString元素。

  • ... [BlobPropertyBag,這里沒有我們的業務]

因此,這里的序列可以是很多東西,從Array到通過多維數組的Set

然后算法將遍歷此序列,直到找到上述三種元素之一。

那么在你的情況下會發生的事情是TypedArray 可以轉換為序列 這意味着當你將它作為直接參數傳遞時, 它將無法看到它的ArrayBuffer ,算法將遍歷其內容並獲取值(此處8位數轉換為字符串),這可能與您的預期不符。

另一方面,當您通過Array包裝Uint8Array時,算法能夠找到Uint8Array指向的BufferSource 所以它將使用它(二進制數據,可能你想要的)。

 var arr = new Uint8Array(25); arr.fill(255); var nowrap = new Blob(arr); var wrapped = new Blob([arr]); test(nowrap, 'no wrap'); test(wrapped, 'wrapped'); function test(blob, msg) { var reader = new FileReader(); reader.onload = e => console.log(msg, reader.result); reader.readAsText(blob); } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM