javascript - koa.js 中的 JSZip 具有流式输入/输出

标签 javascript node.js koa jszip

我正在考虑使用 JSZip 在来自各种下游文件的文件上创建一个 zip 文件。这是我想要做的伪代码:

function* handler () {
    const ids = this.request.body.ids;

    const zip = new JSZip();
    for (let i = 0; i < ids; i++) {
        const r = yield request.get('/some/remote/service/' + ids[i]);
        zip.file(ids[i], r.body);
    }
    this.body = zip.nodeStream():
}  

但想必这将要求所有文件的内容同时存在于内存中,并且在下载所有文件之前不会开始流式传输。

我意识到我可以通过执行以下操作来优化下载时间:

const allFiles = yield ids.map((id) => request.get('/some/remote/service/' + id));

for (let i = 0; i < ids.length; i++) zip.file(ids[i], allFiles[i]);

但主要是我希望有一种方法可以一次只在内存中保存一个文件,并通过 zip 将结果流式传输回客户端。这可以用 JSZip 实现吗?

最佳答案

I'm hoping for a way to only hold one file in memory at a time and stream the result through zip back to the client. Is that possible with JSZip ?

并非没有缺点。 JSZip 不接受 ( yet ) 生成器或函数作为文件内容。它需要文件的完整内容、文件的 promise 或流。这意味着您(还)无法在实际需要内容的最后一刻触发 API 调用。

当您添加流(使用 zip.file("filename.txt", myStream) )时,JSZip 将暂停它并等待某些东西使用它(例如对 zip.generateNodeStream() 的调用或 getter)。

因此,您可以做的(在当前的 v3.1.2 中)限制内存使用量是将所有资源添加为流并调用 zip.generateNodeStream({streamFiles:true}) 。主要缺点是,您确实打开了与 Web 服务的连接,并且在流式传输第一个文件时可能会遇到超时(比如在最后一个文件上)(或者更糟,取决于输入流处理 .pause() 的方式)。

关于streamFiles以及问题的评论:zip 格式非常适合流媒体。正如 the documentation 中所述,streamFiles选项决定 zip 文件内文件的 size/crc32 写入位置:数据之前(但我们需要暂时将文件保存在内存中以计算它们)或数据之后(流式传输所有内容,将计算值放在最后) )。

关于javascript - koa.js 中的 JSZip 具有流式输入/输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39213243/

相关文章:

javascript - 我想为特定时区创建一个 javascript 时钟

javascript - node.js mongodb find()结果到数组但不使用.filter

node.js - 哈巴狗( Jade )模板 : automatically update references to scripts and stylesheets with fingerprinted version in CDN

javascript - 如何在不从模型中移除值的情况下从 UI 中移除值

javascript - 当 Chart.styledMode 设置为 true 时,Highchart 长 y 轴标题可能会与标题重叠

javascript - 使用原型(prototype)从 CSS 类获取颜色

node.js - koa中间件和express中间件有什么不同?

node.js - 无法连接到远程数据库

javascript - 嵌入数组的 MongoDB 平均值作为额外字段

mysql - 当yield一个函数(yield client.query)时,为什么函数的代码不执行?