javascript - 如何将档案 (zip) 通过管道传输到 S3 存储桶
问题描述
我对如何进行有点困惑。我正在使用存档(节点 js 模块)作为将数据写入 zip 文件的一种方式。目前,当我写入文件(本地存储)时,我的代码正在工作。
var fs = require('fs');
var archiver = require('archiver');
var output = fs.createWriteStream(__dirname + '/example.zip');
var archive = archiver('zip', {
zlib: { level: 9 }
});
archive.pipe(output);
archive.append(mybuffer, {name: ‘msg001.txt’});
我想修改代码,以便存档目标文件是 AWS S3 存储桶。查看代码示例,我可以在创建存储桶对象时指定存储桶名称和键(和正文),如下所示:
var s3 = new AWS.S3();
var params = {Bucket: 'myBucket', Key: 'myMsgArchive.zip' Body: myStream};
s3.upload( params, function(err,data){
…
});
Or
s3 = new AWS.S3({ parms: {Bucket: ‘myBucket’ Key: ‘myMsgArchive.zip’}});
s3.upload( {Body: myStream})
.send(function(err,data) {
…
});
关于我的 S3 示例,myStream
它似乎是一个可读流,我很困惑如何使它工作,因为它archive.pipe
需要一个可写流。这是我们需要使用直通流的地方吗?我找到了一个示例,其中有人创建了一个直通流,但该示例过于简洁,无法获得正确理解。我指的具体例子是:
任何人可以给我的帮助将不胜感激。谢谢。
解决方案
这对于想知道如何使用pipe
.
由于您使用传递流正确引用了该示例,因此这是我的工作代码:
1 - 例程本身,使用node-archiver压缩文件
exports.downloadFromS3AndZipToS3 = () => {
// These are my input files I'm willing to read from S3 to ZIP them
const files = [
`${s3Folder}/myFile.pdf`,
`${s3Folder}/anotherFile.xml`
]
// Just in case you like to rename them as they have a different name in the final ZIP
const fileNames = [
'finalPDFName.pdf',
'finalXMLName.xml'
]
// Use promises to get them all
const promises = []
files.map((file) => {
promises.push(s3client.getObject({
Bucket: yourBubucket,
Key: file
}).promise())
})
// Define the ZIP target archive
let archive = archiver('zip', {
zlib: { level: 9 } // Sets the compression level.
})
// Pipe!
archive.pipe(uploadFromStream(s3client, 'someDestinationFolderPathOnS3', 'zipFileName.zip'))
archive.on('warning', function(err) {
if (err.code === 'ENOENT') {
// log warning
} else {
// throw error
throw err;
}
})
// Good practice to catch this error explicitly
archive.on('error', function(err) {
throw err;
})
// The actual archive is populated here
return Promise
.all(promises)
.then((data) => {
data.map((thisFile, index) => {
archive.append(thisFile.Body, { name: fileNames[index] })
})
archive.finalize()
})
}
2 - 辅助方法
const uploadFromStream = (s3client) => {
const pass = new stream.PassThrough()
const s3params = {
Bucket: yourBucket,
Key: `${someFolder}/${aFilename}`,
Body: pass,
ContentType: 'application/zip'
}
s3client.upload(s3params, (err, data) => {
if (err)
console.log(err)
if (data)
console.log('Success')
})
return pass
}
推荐阅读
- python - Python:将 pandas 数据透视表写入 excel 模板
- css - 如何在 CSS 中定位和更改来自(react.js)Formik 的类元素?
- javascript - 使用具有动态文本的相同角度模板
- c# - 登录表单,如何在一个登录表单中使用 3 个表登录?
- javascript - 使用 RxJS / TypeScript / JavaScript 将行转换为列
- twitter-bootstrap - Bootstrap - 导入引导 scss 时 col-size 不起作用
- google-apps-script - 为 Google 表格创建可安装触发器时出现意外错误
- python - 尝试将用户输入同时存储到数组和数据库中
- apache-spark - 可以使用 spark 配置配置 Beam 便携式跑步者吗?
- r - 如何在 R 中创建一个 for 循环来运行一个简单的随机样本并计算每个集合的平均值