如何在不崩溃浏览器的情况下使用IndexedDB创建一个非常长的字符串?

Mat*_*att 29 javascript indexeddb bloburls

我正在编写一个Web应用程序,生成一个用户可以下载的潜在大文本文件,所有处理都在浏览器中完成.到目前为止,我能够以小块的形式读取超过1 GB的文件,处理每个块,逐步生成大量输出文件,并将增长的输出存储在IndexedDB中.我更天真的尝试将所有结果保存在内存中,然后在最后将它们序列化为文件,导致所有浏览器崩溃.

我的问题是双重的:

  1. 我可以追加到IndexedDB中的条目(字符串或数组)而不先将整个内容读入内存吗?现在,这个:

    task.dbInputWriteQueue.push(output);
    var transaction = db.transaction("files", "readwrite");
    var objectStore = transaction.objectStore("files");
    var request = objectStore.get(file.id);
    request.onsuccess = function()
    {
        request.results += nextPartOfOutput
        objectStore.put(request.results);
    };
    
    Run Code Online (Sandbox Code Playgroud)

    输出开始变大后导致崩溃.我可以在数据库中写一堆小条目,但是后来我不得不将它们全部读入内存,以便将它们连接起来.参见我的问题的第2部分......

  2. 我可以创建一个数据对象URL来引用IndexedDB中的值而不将该值加载到内存中吗?对于小字符串我可以做:

    var url = window.URL.createObjectURL(new Blob([myString]), {type: 'text/plain'});
    
    Run Code Online (Sandbox Code Playgroud)

    但对于大字符串,这并不太好.实际上,它在加载字符串之前崩溃了.似乎使用get()IndexedDB的大读取导致Chrome至少崩溃(甚至开发人员工具崩溃).

如果我使用Blob而不是字符串会更快吗?这种转换便宜吗?

基本上我需要一种方法,使用JavaScript,将一个非常大的文件写入磁盘,而不是在任何一点将整个内容加载到内存中.我知道你可以提供createObjectURL一个文件,但这在我的情况下不起作用,因为我正在从用户提供的文件中生成一个文件.

Don*_*mmy 6

存储Blob将使用更少的空间和资源,因为不再需要转换为base64.您甚至可以将"text/plain"对象存储为blob:

var blob = new Blob(['blob object'], {type: 'text/plain'});
var store = db.transaction(['entries'], 'readwrite').objectStore('entries');

// Store the object  
var req = store.put(blob, 'blob');
req.onerror = function(e) {
    console.log(e);
};
req.onsuccess = function(event) {
    console.log('Successfully stored a blob as Blob.');
};
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看更多信息:https: //hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/

自2014年夏天以来,Chrome一直支持此功能:http://updates.html5rocks.com/2014/07/Blob-support-for-IndexedDB-landed-on-Chrome-Dev,因此您无法在旧版本的Chrome上使用此功能.

  • 在存储大约 1Gb 的数据后,将文件存储在 blob 中就会崩溃。 (2认同)