جاوااسکریپت - فشرده کردن جریان تصویر با استفاده از archiver و ارسال آن به عنوان پاسخ express
این بر روی Node/Express/Typescript است. من تلاش میکنم یک تصویر در سیستم فایل خود بگیرم، آن را به یک فایل زیپ استریم کنم و سپس این فایل زیپ را به کلاینت استریم کنم. من باید اطمینان حاصل کنم که هر مرحله استریم میشود چون این به گسترش به زیپ کردن چندین فایل منجر خواهد شد، که باید به صورت استریم به کلاینت تحویل داده شوند.
من کد زیر را دارم:
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();
});
با این حال، وقتی به مسیر /images خود دسترسی پیدا میکنم، یک فایل output.zip دریافت میکنم که خالی است.
احساس میکنم که somehow ترتیب لولههایم را به هم زدهام.
من چه چیزی را از دست دادهام؟
پاسخ شماره ۱
مشکل را پیدا کردم. این هم کدی است که کار میکند:
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();
});
من مجبور شدم از archive.append(ps, {name: "image.png"}); استفاده کنم تا جریان تصویر خود را به آرشیو زیپ اضافه کنم.
