Javascript 如何使用IndexedDB生成一个真正长的字符串而不破坏浏览器?

Javascript 如何使用IndexedDB生成一个真正长的字符串而不破坏浏览器?,javascript,indexeddb,bloburls,Javascript,Indexeddb,Bloburls,我正在编写一个web应用程序,它生成一个用户将下载的可能很大的文本文件,所有处理都在浏览器中完成。到目前为止,我能够以小块的形式读取超过1GB的文件,处理每个块,以增量的方式生成一个大的输出文件,并将不断增长的输出存储在IndexedDB中。我更天真的尝试是将所有结果保存在内存中,然后在最后将它们序列化为一个文件,这导致所有浏览器崩溃 我的问题有两个方面: 我是否可以在不首先将整个内容读入内存的情况下附加到IndexedDB中的条目(字符串或数组)?现在,这是: task.dbInputWrit

我正在编写一个web应用程序,它生成一个用户将下载的可能很大的文本文件,所有处理都在浏览器中完成。到目前为止,我能够以小块的形式读取超过1GB的文件,处理每个块,以增量的方式生成一个大的输出文件,并将不断增长的输出存储在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);
    };
    
    在输出开始变大后导致崩溃。我可以将一堆小条目写入数据库,但随后我必须将它们全部读入内存,以便将它们连接起来。见我问题的第二部分

  • 我可以创建一个数据对象URL来引用IndexedDB中的值,而不将该值加载到内存中吗?对于小字符串,我可以执行以下操作:

    var url = window.URL.createObjectURL(new Blob([myString]), {type: 'text/plain'});
    
    但是对于大的弦来说,这个摇摆不太好。事实上,它在加载字符串之前崩溃。似乎使用IndexedDB中的
    get()
    进行大读取至少会导致Chrome崩溃(甚至开发工具也会崩溃)

  • 如果我使用blob而不是string,会更快吗?这种转换便宜吗


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

    存储Blob将使用更少的空间和资源,因为不再需要转换为base64。您甚至可以将“文本/普通”对象存储为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.');
    };
    
    您可以在此处查看更多信息:


    Chrome仅在2014年夏天才支持此功能:因此您不能在较旧版本的Chrome上使用此功能。

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

    使用文件系统API(在重新发布之前已被弃用)是不可能的吗?嗨,Matt,恐怕这只可能在chrome上使用文件系统API,我已经实现了这样的解决方案,我能够创建高达4GB的文件,另一种解决方案是将数据发送到服务器并在那里创建文件。在他们向文件API添加写函数之前,浏览器中不可能这样做。正如@DeniSpasovski所建议的,尝试“将数据发送到服务器并在那里创建文件”。另外,发布它,而不是使用
    GET
    ,因为
    post
    允许发送比
    GET
    更多的数据。如果您的目标只是桌面浏览器,另一个方向可能是一个选项-使用swf生成文件-@agiHammer。。我要等待1-4Gb的上传;在存储了大约1Gb的数据后,将文件以blob的形式存储会失败。我认为直到现在,如果不将文件加载到内存中,就无法将要下载的文件放入js中。使用文件存储,它无论如何都会崩溃,但该API仅在Chrome上可用