Wie kann ich mit IndexedDB einen wirklich langen String erstellen, ohne den Browser zum Absturz zu bringen?
Ich schreibe eine Web-App, die eine möglicherweise große Textdatei generiert, die der Benutzer herunterladen wird, und die gesamte Verarbeitung erfolgt im Browser. Bisher bin ich in der Lage, eine Datei über 1 GB in kleinen Blöcken zu lesen, jeden Block zu verarbeiten, eine große Ausgabedatei inkrementell zu generieren und die wachsende Ausgabe in IndexedDB zu speichern. Mein naiverer Versuch, alle Ergebnisse im Speicher zu behalten und sie am Ende in eine Datei zu serialisieren, führte zum Absturz aller Browser.
Meine Frage ist zweifach:
Kann ich an einen Eintrag in IndexedDB (entweder einen String oder ein Array) anhängen, ohne das Ganze zuerst in den Speicher zu lesen? Im Moment ist dies:
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);
};
führt zu Abstürzen, nachdem die Ausgabe zu groß wird. Ich könnte einfach ein paar kleine Einträge in die Datenbank schreiben, aber dann müsste ich sie sowieso später alle in den Speicher einlesen, um sie zu verketten. Siehe Teil 2 meiner Frage ...
Kann ich eine Datenobjekt-URL erstellen, um auf einen Wert in IndexedDB zu verweisen, ohne diesen Wert in den Speicher zu laden? Für kleine Streicher kann ich:
var url = window.URL.createObjectURL(new Blob([myString]), {type: 'text/plain'});
Aber für große Saiten ist das nicht so gut. Tatsächlich stürzt es ab, bevor der String geladen wird. Es scheint, dass große liest mitget()
von IndexedDB führt zumindest zum Absturz von Chrome (selbst die Entwicklertools stürzen ab).
Wäre es schneller, wenn ich Blobs anstelle von Strings verwenden würde? Ist der Umbau günstig?
rundsätzlich brauche ich eine Möglichkeit, mit JavaScript eine wirklich große Datei auf die Festplatte zu schreiben, ohne das Ganze zu irgendeinem Zeitpunkt in den Speicher zu laden. Ich weiß, dass Sie @ geben könncreateObjectURL
eine Datei, aber das funktioniert in meinem Fall nicht, da ich ein @ generieNe -Datei von einer vom Benutzer bereitgestellten.