【问题标题】:Why is Blob of Array smaller than Blob of Uint8Array?为什么 Array 的 Blob 比 Uint8Array 的 Blob 小?
【发布时间】:2018-09-08 04:49:13
【问题描述】:

我使用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 包装在一个数组中。这是为什么呢?

【问题讨论】:

    标签: javascript blob arraybuffer uint8array


    【解决方案1】:

    参照。 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 无法使用。

    所以,底线是,第一个版本是正确的方法。

    【讨论】:

      【解决方案2】:

      不幸的是,MDN 文章在这里几乎是错误的,而且充其量是误导。

      From the specs:

      可以使用以下参数调用 Blob() 构造函数:

      • blobParts 序列 它采用任意数量的以下类型的元素,并且以任意顺序:

        • BufferSource 元素。

        • Blob 元素。

        • USVString 元素。

      • ... [BlobPropertyBag,这里不关我们的事]

      所以这里的一个序列可以是很多东西,从一个Array到一个Set通过一个多维数组。

      那么算法就是遍历这个序列,直到找到上面的三种元素之一。

      所以在您的情况下发生的是 TypedArray 可以转换为序列。这意味着当你将它作为直接参数传递时,它将无法看到它的 ArrayBuffer 并且算法将遍历其内容并获取值(这里是 8 位数字转换为字符串),这可能不是您所期望的。

      另一方面,当你将你的 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);
      }

      【讨论】:

        猜你喜欢
        • 2021-10-31
        • 1970-01-01
        • 2023-01-29
        • 2012-12-29
        • 2016-03-29
        • 2022-01-09
        • 2016-08-28
        • 1970-01-01
        • 2017-11-01
        相关资源
        最近更新 更多