javascript - Komprimera bildström med archiver och skicka som express-svar
Detta är på Node/Express/Typescript. Jag försöker få en bild på mitt filsystem, strömma den till en zip-fil och sedan strömma denna zip-fil till klienten. Jag måste se till att varje steg strömmas eftersom detta kommer att utökas till att zippa flera filer, som måste strömmas till klienten som en zip.
Jag har följande kod:
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();
});
Men när jag går till min /images-rutt får jag en output.zip-fil som är tom.
Jag känner att jag på något sätt blandar ihop ordningen på mina rör.
Vad missar jag?
Svar #1
Jag lista ut problemet. Här är koden som fungerar:
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();
});
Jag var tvungen att använda archive.append(ps, {name: "image.png"}); för att lägga till min bildström i zip-arkivet.
