Blob二进制数据存储在哪里?

时间:2016-07-07 07:03:46

标签: javascript blob

鉴于

var data = new Array(1000000);
for (var i = 0; i < data.length; i++) {
  data[i] = 1;
}
var blob = new Blob([data]);

哪里是存储数组的二进制数据表示?

4 个答案:

答案 0 :(得分:14)

所有未在任何其他存储中明确表示的变量都存储在内存(RAM)中,直到程序结束或取消设置(从内存中清除)。

TLDR; 在RAM中

答案 1 :(得分:8)

这不会完全回答你的问题。

  

那么当宣布new Blob()时会发生什么?

来自official fileAPI documentation

The Blob() constructor can be invoked with zero or more parameters. When the Blob() constructor is invoked, user agents must run the following Blob constructor steps:
[1] If invoked with zero parameters, return a new Blob object with its readability state set to OPENED, consisting of 0 bytes, with size set to 0, and with type set to the empty string.
[2] Otherwise, the constructor is invoked with a blobParts sequence. Let a be that sequence.
[3] Let bytes be an empty sequence of bytes.
[4] Let length be `a`s length. For 0 ≤ i < length, repeat the following steps:
    1. Let element be the ith element of a.
    2. If element is a DOMString, run the following substeps:
        Let s be the result of converting element to a sequence of Unicode characters [Unicode] using the algorithm for doing so in WebIDL.
        Encode s as UTF-8 and append the resulting bytes to bytes.
    Note:
        The algorithm from WebIDL [WebIDL] replaces unmatched surrogates in an invalid UTF-16 string with U+FFFD replacement characters. Scenarios exist when the Blob constructor may result in some data loss due to lost or scrambled character sequences.  

    3. If element is an ArrayBufferView [TypedArrays], convert it to a sequence of byteLength bytes from the underlying ArrayBuffer, starting at the byteOffset of the ArrayBufferView [TypedArrays], and append those bytes to bytes.
    4. If element is an ArrayBuffer [TypedArrays], convert it to a sequence of byteLength bytes, and append those bytes to bytes.
    5. If element is a Blob, append the bytes it represents to bytes. The type of the Blob array element is ignored.  
[5] If the type member of the optional options argument is provided and is not the empty string, run the following sub-steps:
    1. Let t be the type dictionary member. If t contains any characters outside the range U+0020 to U+007E, then set t to the empty string and return from these substeps.
    2. Convert every character in t to lowercase using the "converting a string to ASCII lowercase" algorithm.
[6] Return a Blob object with its readability state set to OPENED, referring to bytes as its associated byte sequence, with its size set to the length of bytes, and its type set to the value of t from the substeps above. 

Blob与任何其他ArrayBuffer一样存储在内存中。它存储在ram中,就像在窗口中声明的其他对象一样。

查看chrome://blob-internals,我们可以看到它是如何物理存储在ram中的。这是一个示例blob。

c7828dad-dd4f-44e6-b374-9239dbe35e35
    Refcount: 1
    Status: BlobStatus::DONE: Blob built with no errors.
    Content Type: application/javascript
    Type: file
    Path: /Users/Chetan/Library/Application Support/Google/Chrome/Default/blob_storage/c7828dad-dd4f-44e6-b374-9239dbe35e35/0
    Modification Time: Monday, June 5, 2017 at 4:29:53 PM
    Offset: 4,917,846
    Length: 224,733

在打印blob的实际内容时,我们得到一个普通的js文件。

$ cat c7828dad-dd4f-44e6-b374-9239dbe35e35/0

...
html {
   font-family: sans-serif;
   /* 1 */
   -ms-text-size-adjust: 100%;
   /* 2 */
   -webkit-text-size-adjust: 100%;
   /* 2 */ }

/**
 * Remove default margin.
 */
body {
    margin: 0; }
...

答案 2 :(得分:5)

Blob存储在内存中。在浏览器blob存储中。如果创建blob对象,可以在Firefox内存分析器(about:memory)中进行检查。 这里我们可以看到firefox输出的一个例子,选择了文件。 Blob和File之间存在差异。 Blob存储在内存中,文件存储在文件系统中。

651.04 MB (100.0%) -- explicit
├──430.49 MB (66.12%) -- dom
│  ├──428.99 MB (65.89%) -- memory-file-data
│  │  ├──428.93 MB (65.88%) -- large
│  │  │  ├────4.00 MB (00.61%) ── file(length=2111596, sha1=b95ccd8d05cb3e7a4038ec5db1a96d206639b740)
│  │  │  ├────4.00 MB (00.61%) ── file(length=2126739, sha1=15edd5bb2a17675ae3f314538b2ec16f647e75d7)

Google Chrome中存在错误。 Chrome有blob限制。当您创建总blob量超过500mb时。浏览器将停止创建blob,因为blob存储达到了500mb的限制。避免这种情况的唯一方法是将一个blob写入IndexDb并从IndexDb中删除。当blob写入indexDb时,blob对象将自动保存到文件系统(blob将转换为文件)。 在您停止使用垃圾收集器之后,将使用垃圾收集器从内存中清除Blob,或者使blob = null。但GC会在一段时间后删除blob,而不是瞬间删除。

答案 3 :(得分:2)

Blob代表一堆可以在任何地方存在的数据。 File API specification故意不提供任何同步方式来读取Blob的内容。

这里有一些具体的可能性。

  1. 当您通过构造函数创建Blob并将其传递到内存中的数据(如Uint8Array)时,Blob的内容将至少在一段时间内保留在内存中。
  2. 当您从<input type="file">获取Blob时,Blob的内容将保存在磁盘上,位于用户选择的文件中。规范中提到了快照,但是没有实现,因为这会给用户操作带来很大的延迟。
  3. 当您从另一个客户端存储API(例如IndexedDB或Cache Storage API)获得Blob时,Blob的内容将存储在API磁盘上的后备存储中。
  4. 某些API可能会返回一个Blob,其数据来自网络。 XMLHttpRequest规范使这成为不可能,并且我认为获取规范还要求在创建Blob之前检索整个响应。但是,将来可能会有流HTTP响应的规范。
  5. 通过Blob构造函数通过数组片段创建的Blob的内容可能分散在上述所有位置。

在Chrome中,我们使用多进程架构,其中浏览器进程具有所有活动Blob的中央注册表,并充当Blob内容的真实来源。在渲染器中(通过JavaScript)创建Blob时,取决于Blob的大小,其内容将通过IPC,共享内存或临时文件移动到浏览器进程。浏览器进程也可能会将内存Blob内容逐出到临时文件中。上一个答案中提到的500mb限制是在2016年左右取消的。更多实施细节在the README for Chrome's Blobs subsystem中。