Выбор ответа Junior Потоки и буферы спрашивают часто обновлено

Как отдать большой файл по HTTP

Вопрос

Нужно отдать клиенту файл на 4 ГБ, не съев память сервера. Какой вариант правильный?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: await pipeline(fs.createReadStream(path), res). Поток читает файл кусками по 64 КБ, а pipeline учитывает backpressure: если клиент качает медленно, чтение приостанавливается.

Варианты ответа

  1. res.end(await fs.promises.readFile(path))
  2. res.end(fs.readFileSync(path))
  3. await pipeline(fs.createReadStream(path), res)правильный ответ
  4. res.write(await fs.promises.readFile(path, "utf8"))

Разбор

Поток читает файл кусками по 64 КБ, а pipeline учитывает backpressure: если клиент качает медленно, чтение приостанавливается. Память занята только буферами.

  • Оба варианта с readFile пытаются загрузить все 4 ГБ в память. На деле readFile для файла больше 2 ГБ вообще бросит ERR_FS_FILE_TOO_LARGE.
  • readFileSync вдобавок блокирует event loop.
  • Чтение как utf8 ещё и испортит бинарный файл.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.