#node.js #parsing #stream #multipartform-data #hapi
#node.js #синтаксический анализ #поток #multipartform-данные #hapi
Вопрос:
У меня есть конечная точка, которая получает поток:
server.route({
method: 'PUT',
path: `${FILES_PREFIX}`,
handler: Handlers.createFile,
options: {
description: 'Create file.',
tags: ['api', 'file'],
payload: {
timeout: false,
maxBytes: 10 * GB,
output: 'stream',
multipart: true,
parse: false,
allow: 'multipart/form-data',
}
}
});
Если я установлю parse: true, я получу свой буфер, как и ожидалось, и смогу прочитать его в payload.data. Однако, поскольку мои файлы слишком большие, мне нужно проанализировать их самостоятельно (в противном случае я получаю: RangeError [ERR_OUT_OF_RANGE]: значение «длина» находится вне диапазона. Оно должно быть>= 0 amp;amp; <= 2147483647. Получено 2877227008)
Итак, решение, которое я пытаюсь, — установить parse: false и самостоятельно проанализировать поток. Однако, когда я смотрю на свою полезную нагрузку, я вижу, что у меня есть readableBuffer(), который возвращает мне список буферов… но список буферов содержит только 1 элемент размером 64 КБ. Значение first element .next равно null . Я просто остался там, спрашивая, где остальные мои данные.
Я также попытался просмотреть request.raw.req, поскольку синтаксический анализ false, у меня все равно не должно быть всех данных в буфере… но в основном это одна и та же информация в request.raw.req и request.payload. У меня также есть readableBuffer размером 64 КБ по запросу.raw.req().readableBuffer()
Ответ №1:
Анализатор по умолчанию определенно не подходит для передач такого размера, поскольку он буферизует все входящие данные в память.
Вы на правильном пути, но вы не используете stream API по назначению. readableBuffer()
Метод возвращает только то, что в данный момент буферизовано. Чтобы получить больше данных и правильно их использовать, вам нужно будет использовать соответствующий stream API:
- Использование
'data
amp;'end'
событий. - Использование
stream.read()
с'readable'
событием. - Просто
stream.pipe()
в другой поток.
Для всего этого вам нужно будет зарегистрироваться и 'error'
соответствующим образом обработать событие.
Наиболее современным подходом является использование помощника Stream.pipeline().
Наконец, поток может быть не лучшим решением. Hapi также поддерживает 'file'
режим вывода, который будет передавать входные данные непосредственно в файл на диске.