我正在编写一个 Web 应用程序,它会生成一个可能很大的文本文件,用户将下载该文件,并且所有处理都在浏览器中完成。到目前为止,我能够以小块读取超过 1 GB 的文件,处理每个块,逐步生成大输出文件,并将不断增长的输出存储在 IndexedDB 中。我更天真的尝试将所有结果保存在内存中,然后在最后将它们序列化到一个文件中,这导致所有浏览器崩溃。
我的问题有两个:
我可以在不先将整个内容读入内存的情况下附加到 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); };
在输出开始变大后导致崩溃。我可以只将一堆小条目写入数据库,但无论如何我必须稍后将它们全部读入内存以连接它们。请参阅我的问题的第 2 部分...
我可以创建一个数据对象 URL 来引用 IndexedDB 中的一个值而不将该值加载到内存中吗?对于小字符串,我可以这样做:
var url = window.URL.createObjectURL(new Blob([myString]), {type: 'text/plain'});
但是对于大字符串,这并不太好。事实上,它在加载字符串之前就崩溃了。似乎使用
get()
IndexedDB 的大读取至少会导致 Chrome 崩溃(甚至开发人员工具也会崩溃)。
如果我使用 Blob 而不是字符串会更快吗?这种转换便宜吗?
基本上我需要一种方法,使用 JavaScript,将一个非常大的文件写入磁盘,而无需在任何时候将整个文件加载到内存中。我知道您可以提供createObjectURL
一个文件,但这在我的情况下不起作用,因为我正在从用户提供的文件中生成一个新文件。