Читать большой JSON Blob/Stream/Buffer только вперед в браузере только Javascript?

avatar
Luke Vo
8 августа 2021 в 21:58
157
0
0

У меня есть файл JSON размером около 800 МБ, и я никак не могу загрузить его в память, даже с FileReader.readAsText (свойство результата — пустая строка). Я не думаю, что это актуально, но файл JSON представляет собой массив из примерно 3,5 миллионов мелких объектов. Обратите внимание, что файл выбирается пользователем в браузере и никогда не покидает его. Вся обработка происходит в браузере.

Я попробовал Oboe.js и смог передать ввод, но через некоторое время он останавливается. Глядя на событие, я предполагаю, что Oboe хранит все объекты JSON, которые он анализирует. Если я правильно понимаю, их браузерная версия также не поддерживает потоковую передачу.

Есть ли способ переадресации чтения JSON? Я не против того, чтобы у меня не было предыдущего состояния, похожего на .NET Utf8JsonReader?


Вот моя текущая попытка с гобоем:

    async loadAsync(file: Blob) {
        const blocks: any[] = this.blocks = [];
        
        await new Promise<void>(r => {
            const ms = Date.now();
            const url = URL.createObjectURL(file);
            let counter = 0;

            oboe(url)
                .node("!.[*]", (block: any) => {
                    blocks.push(block);

                    counter++;
                    if (counter % 5000 == 0) {
                        this.logFn(`Loading: ${counter} items so far.`);
                    }
                })
                .done((fullJson: any) => {
                    debugger;
                    this.logFn(`Finished loading ${counter} blocks in ${Date.now() - ms}ms`);
                    r();
                })
                .fail((err: any) => {
                    console.error(err);
                    this.logFn(err);
                });
        });
    }

Это хорошо работает для небольших файлов, но для больших файлов после примерно 250 тыс. элементов появляется эта ошибка:

enter image description here

Источник
Kaiido
9 августа 2021 в 01:19
1

JS-движки имеют константу максимальной длины строки (512 МБ в V8). Но вы все равно можете прочитать этот файл как текст в потоке, просто вызовите <22219162333190> и передайте его в TextDecoderStream, где это возможно, или даже просто передать каждый фрагмент этого потока обычному TextDecoder, передав параметр { stream: true } в его методе decode(). Однако для декодирования JSON... Вам придется написать его самостоятельно (или найти того, кто это сделал).

Luke Vo
9 августа 2021 в 06:39
0

@Kaiido Спасибо за информацию об ограничениях. Я знал о Stream, но, как вы сказали, проблема в том, что я не могу найти парсер JSON с потоком/неполными данными, кроме Oboe. К сожалению, то, как они работают, перестает работать после превышения лимита.

Ответы (0)