Como criar uma sequência muito longa usando o IndexedDB sem travar o navegador?
Estou escrevendo um aplicativo Web que gera um arquivo de texto potencialmente grande que o usuário fará o download e todo o processamento é feito no navegador. Até agora, sou capaz de ler um arquivo com mais de 1 GB em pequenos pedaços, processar cada pedaço, gerar um grande arquivo de saída incrementalmente e armazenar a saída crescente no IndexedDB. Minha tentativa mais ingênua, que manteve todos os resultados na memória e os serializou em um arquivo no final, estava causando a falha de todos os navegadores.
Minha pergunta é dupla:
Posso anexar a uma entrada no IndexedDB (uma string ou uma matriz) sem antes ler a coisa toda na memória? Agora, isso:
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);
};
está causando falhas depois que a saída começa a ficar grande. Eu poderia simplesmente escrever um monte de pequenas entradas no banco de dados, mas teria que ler todas elas na memória mais tarde para concatená-las. Veja a parte 2 da minha pergunta ...
Posso criar um URL de objeto de dados para referenciar um valor no IndexedDB sem carregar esse valor na memória? Para cordas pequenas, eu posso fazer:
var url = window.URL.createObjectURL(new Blob([myString]), {type: 'text/plain'});
Mas para cordas grandes, isso não funciona muito bem. De fato, ele trava antes que a string seja carregada. Parece que grandes leituras usandoget()
do IndexedDB faz com que o Chrome, pelo menos, trave (até mesmo as ferramentas do desenvolvedor).
Seria mais rápido se eu estivesse usando Blobs em vez de strings? Essa conversão é barata?
Basicamente, preciso de uma maneira, com JavaScript, de gravar um arquivo muito grande no disco sem carregar a coisa toda na memória a qualquer momento. Eu sei que você pode darcreateObjectURL
um arquivo, mas isso não funciona no meu caso, pois estou gerando umNovo arquivo de um que o usuário fornece.