Я пишу веб-приложение, которое генерирует потенциально большой текстовый файл, который будет загружен пользователем, и вся обработка выполняется в браузере. Пока я могу читать файл объемом более 1 ГБ в небольших кусках, обрабатывать каждый фрагмент, генерировать большой выходной файл пошагово и хранить растущий результат в 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, по крайней мере, сбой (даже при сбое инструментов разработчика).
Было бы быстрее, если бы я использовал Blobs вместо строк? Это дешевая конверсия?
В принципе, мне нужно с помощью JavaScript написать действительно большой файл на диске, не загружая все это в память в любой момент. Я знаю, что вы можете предоставить createObjectURL
файл, но это не работает в моем случае, так как я создаю новый файл из того, который предоставляет пользователь.