avoid having many useless file open while zipping

Massimo Melina committed Jan 19, 2022 at 23:12 UTC d25e5e30ed7405d3d90ec0beba5b017e7b29c80e
2 files changed +12 -5
src/QuickZipStream.ts
+3 -2
@@ -11,7 +11,7 @@ const crc32provider = import('@node-rs/crc32').then(lib => lib.crc32, () => {
11
12 interface ZipSource {
13 path: string
14 - data: Readable
14 + getData: () => Readable // deferred stream, so that we don't keep many open files because of calculateSize()
15 size: number
16 ts: Date
17 }
@@ -68,7 +68,8 @@ export class QuickZipStream extends Readable {
68 if (!file)
69 return this.closeArchive()
70 ++this.numberOfFiles
71 - let { path, data, size, ts } = file
71 + let { path, getData, size, ts } = file
72 + const data = getData()
73 const pathAsBuffer = Buffer.from(path, 'utf8')
74 const crc32 = await crc32provider
75 let crc: number | undefined = undefined
src/zip.ts
+9 -3
@@ -13,13 +13,19 @@ export async function zipStreamFromFolder(node: VfsNode, ctx: Koa.Context) {
13 ctx.attachment((name || 'archive') + '.zip')
14 const filter = pattern2filter(String(ctx.query.search||''))
15 const walker = filterMapGenerator(walkNode(node, ctx, Infinity), async (el:VfsNode) => {
16 - if (!el.source || ctx.req.aborted || !filter(el.name))
16 + const { source } = el
17 + if (!source || ctx.req.aborted || !filter(el.name))
18 return
19 try {
19 - const st = await fs.stat(el.source)
20 + const st = await fs.stat(source)
21 if (!st || !st.isFile())
22 return
22 - return { path:el.name, size:st.size, ts:st.mtime||st.ctime, data: createReadStream(el.source) }
23 + return {
24 + path: el.name,
25 + size: st.size,
26 + ts: st.mtime || st.ctime,
27 + getData: () => createReadStream(source)
28 + }
29 }
30 catch {}
31 })