Я использую Nodejs для создания файла JSON из действительно большого объекта JSON (1 ГБ). Чтобы избежать проблем с памятью, я использую createWriteStream :
var writeStream = fs.createWriteStream('./output/outPut.json')
После использования Builder (пользовательская функция) он вернет большой объект JSON.
Последний шаг - создать этот файл:
writeStream.write(JSON.stringify(search_index), (err) => {
if (err) throw err
console.info('File Ready... ')
})
Но, к сожалению, JSON.stringify нельзя использовать с таким тяжелым объектом.
JSON.stringify выдает RangeError: недопустимая длина строки для огромных объектов
Подскажите, пожалуйста, есть ли решение этой проблемы?
@Craicerjack Я использую elasticlunr JS для создания модуля поиска в своем приложении, и этот файл является поисковым индексом, к сожалению, его нельзя разделить на несколько файлов.
Отвечает ли это на ваш вопрос? Парсинг большого файла JSON в Nodejs
@RishabhDeepSingh, этот ответ о том, как читать большой JSON, а не создавать его
SearchIndex массив или объект?
При записи больших наборов данных в файлы (т. е. большого количества документов в поисковом индексе) обычно лучше работать с меньшими пакетами, чтобы найти баланс между потреблением памяти и временем вычислений.
Например, вы можете создать 100 объектов JavaScript (n = 100), stringify их, добавить в свой файл и продолжить со следующими 100 объектами.
Хитрость здесь заключается в том, чтобы определить размер пакета n, который эффективно использует память вашей системы, не тратя слишком много времени на операции чтения/записи файлов.
Распространенной ошибкой является то, что общее количество ваших документов может не быть целым числом, кратным размеру вашего пакета n. При повторении с использованием индексной переменной с отсчетом от нуля вы должны записать в файл, если:
Index % n === 0 || index === (totalCount - 1)
Дополнительным преимуществом является то, что вы можете запустить/перезапустить этот процесс после ошибки без необходимости воссоздавать все данные (т. е. если какая-то ошибка возникает после записи 800 МБ данных, вы можете зарегистрировать последний успешный индекс и продолжить оттуда).
Поток записи бесполезен, если вы записываете только одну большую строку. Вы не можете использовать родной JSON.stringify здесь. Однако существует довольно много доступных библиотек, которые будут реализовывать сериализацию JSON в поток (и даже больше для десериализации из потока), используйте одну из них.
Первый шаг - инициализировать объект потока.
const writeStream = fs.createWriteStream('./object.json', { flags: 'w' })
Затем преобразование моих данных в строку JSON (stringify) Использование модуля JSON Stream Stringify
const JsonStreamStringify = require('json-stream-stringify')
const jsonStream = new JsonStreamStringify(Promise.resolve(Promise.resolve(TargetData)))
Последний шаг — передать возвращенные данные в writeStream.
jsonStream.pipe(writeStream)
jsonStream.on('end', () => console.info('done '))
Но это может занять много времени в моем случае 10-15 мин (1,1 Гб)
Какова цель создания такого большого файла. Можете ли вы разделить информацию на более мелкие файлы?