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

How can I make a really long string using IndexedDB without crashing the browser?

我正在编写一个Web应用程序,该应用程序生成一个用户将下载的可能较大的文本文件,所有处理都在浏览器中完成。到目前为止,我能够以小块的形式读取超过1GB的文件,处理每个块,增量生成一个大的输出文件,并将不断增长的输出存储在indexeddb中。我更多的呐?试图将所有结果保存在内存中,然后在最后将它们序列化到一个文件中,这会导致所有浏览器崩溃。

我的问题是双重的:

  • 我可以附加到indexeddb中的一个条目(字符串或数组)而不首先将整个内容读取到内存中吗?现在,这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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);
    };

    在输出开始变大后导致崩溃。我可以在数据库中写一些小条目,但是稍后我必须将它们全部读到内存中,以便将它们连接起来。见我问题的第二部分…

  • 我可以创建一个数据对象URL来引用indexeddb中的值而不将该值加载到内存中吗?对于细线,我可以做到:

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

    但对于大弦来说,这并不是很好地摇摆。实际上,它在加载字符串之前崩溃。似乎使用indexeddb中的get()进行大读取会导致chrome崩溃(甚至开发工具崩溃)。

  • 如果我用斑点代替字符串会更快吗?转换便宜吗?

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


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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.');
    };

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

    Chrome仅在2014年夏季才支持此功能:http://updates.html5rocks.com/2014/07/blob-support-for-indexeddb-landed-on-chrome-dev,因此不能在旧版本的Chrome上使用此功能。


    我刚刚重新打开了两年前提交的chrome bug,并为FF团队创建了另一个bug,与创建大型blob时浏览器崩溃相关。对于浏览器来说,生成大文件不应该是一个问题。