Esto está en Node/Express/Typescript. Estoy tratando de obtener una imagen en mi sistema de archivos, transmitirla a un archivo zip y luego transmitir este archivo zip al cliente. Tengo que asegurarme de que cada paso se transmita, ya que esto se expandirá para comprimir varios archivos, que deben transmitirse al cliente como un archivo zip.
Tengo el siguiente código:
import express, { Application, Request, Response } from "express"; import fs from "fs"; import stream from "stream"; import archiver from "archiver"; app.get("/images", async (req: Request, res: Response) => { const r = fs.createReadStream("appicon.png"); const ps = new stream.PassThrough(); // stream the image stream.pipeline( r, ps, (err) => { if (err) { console.log(err); return res.sendStatus(400); } } ); // zip the image and send it let archive = archiver("zip"); archive.on("end", () => { console.log(archive.pointer() + " total bytes"); console.log("archiver finalized"); }) archive.on('error', (err) => { return res.status(500).send({ message: err }); }) res.attachment('output.zip'); ps.pipe(archive); archive.pipe(res); archive.finalize(); });Sin embargo, cuando accedo a mi ruta /images, obtengo un archivo output.zip que está vacío.
Siento que estoy estropeando el orden de mis tuberías de alguna manera.
¿Qué me estoy perdiendo?
Descubrí el problema. Aquí está el código que funciona:
app.get("/images", async (req: Request, res: Response) => { const r = fs.createReadStream("appicon.png"); const ps = new stream.PassThrough(); stream.pipeline( r, ps, (err) => { if (err) { console.log(err); return res.sendStatus(400); } } ); //r.pipe(ps); // alternative way to do it without pipeline // zip the image and send it let archive = archiver("zip"); archive.on("end", () => { console.log(archive.pointer() + " total bytes"); console.log("archiver finalized"); }) archive.on('error', (err) => { return res.status(500).send({ message: err }); }) // name the output file res.attachment("output.zip"); // pipe the zip to response archive.pipe(res); // add the image from stream to archive archive.append(ps, {name: "image.png"}); archive.finalize(); }); Tuve que usar archive.append(ps, {name: "image.png"}); para agregar mi secuencia de imágenes al archivo zip.