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中的
如果我用斑点代替字符串会更快吗?转换便宜吗?
基本上,我需要一种方法,使用JavaScript,将一个非常大的文件写入磁盘,而不需要在任何一点将整个文件加载到内存中。我知道你可以给
存储一个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时浏览器崩溃相关。对于浏览器来说,生成大文件不应该是一个问题。