我正在使用这个问题中的代码来使用节点归档器归档文件并将它们传输到S3。我的特定任务需要我从url下载大量文件,将它们压缩成一个归档文件,然后传输到S3。
我用的是"got">
for (const file of files) {
const { resultFileName, fileUrl} = getFileNameAndUrl(file);
if (!fileUrl)
continue;
const downloadStream = got.stream(fileUrl, {
retry: {
limit: 5
}
});
archive.append(downloadStream, { name: resultFileName });
}
代码的其余部分与最初的问题几乎相同。问题是脚本不能很好地处理大量文件(它只是在某个点完成执行)。
在完美的情况下-我希望这个脚本下载文件,将它们附加到存档并使用管道将它们传输到S3。最好的方法是批量下载(就像《Promise》那样)。在bluebird中使用并发映射)。我只是不知道如何使用Streams,因为我没有太多的使用经验。
archiver
包一次处理一个文件,因此没有必要与got
并行下载多个文件。遵循您提供的链接的示例,它应该工作。
还有,不要打开大量的流,所有的文件都应该压缩。依次执行,因为流和archived
包在打开的流上有超时。
希望这对你有帮助。
注意:我无法测试这个,因为我没有访问aws s3的权限。
这段代码应该下载网页并保存在zip文件中,其中应该包含fs.html
&index.html
文件。
// file:main.mjs
import got from 'got'
import archiver from 'archiver'
import S3 from 'aws-sdk/clients/s3'
import { basename } from 'path'
try {
const urls = ['https://nodejs.org/api/fs.html', 'https://nodejs.org/api/index.html']
const gotconfig = {}
const archive = archiver('zip', {
zlib: { level: 9 },
})
archive.on('warning', function (err) {
if (err.code === 'ENOENT') {
} else {
throw err
}
})
archive.on('error', function (err) {
throw err
})
for (const url of urls) {
// const _url = new URL(url)
archive.append(got.stream(url, gotconfig), { name: basename(url) })
}
const s3 = new S3()
await s3.upload({ Bucket: 'buck', Key: 'key', Body: archive }).promise()
await archive.finalize()
} catch (error) {
console.error(error)
}
这个我已经测试过了&它的工作原理。与上面类似,但在/tmp/test1.zip
中保存zip文件。
// file: local.mjs
import got from 'got'
import { createWriteStream } from 'fs'
import archiver from 'archiver'
import { basename } from 'path'
try {
const urls = ['https://nodejs.org/api/fs.html', 'https://nodejs.org/api/index.html']
const gotconfig = { }
const output = createWriteStream('/tmp/test1.zip')
const archive = archiver('zip', {
zlib: { level: 9 },
})
output.on('close', function () {
console.log(archive.pointer() + ' total bytes')
console.log('archiver has been finalized and the output file descriptor has closed.')
})
output.on('end', function () {
console.log('Data has been drained')
})
archive.on('warning', function (err) {
if (err.code === 'ENOENT') {
} else {
throw err
}
})
archive.on('error', function (err) {
throw err
})
archive.pipe(output)
for (const url of urls) {
archive.append(got.stream(url, gotconfig), { name: basename(url) })
}
await archive.finalize()
} catch (error) {
console.error(error)
}