使用createWriteStream上传至Amazon S3出现空文件问题求助
问题:使用createWriteStream上传S3出现0B空文件,readFileSync却正常
在使用fs.createWriteStream上传文件到Amazon S3存储桶时,未出现任何错误,但上传的图片是空文件(大小为0B),相关代码如下:
const uploadImage = async (filePath, fileId) => { const fileStream = fs.createWriteStream(filePath); const uploadParams = { Bucket: bucket, ACL: "public-read", Body: fileStream, Key: filePath, ContentType: "image/png", }; console.log(filePath); const data = await s3.upload(uploadParams).promise(); console.log(data); return; };
但使用fs.readFileSync时,图片可正常上传,代码如下:
const uploadImage = async (filePath, fileId) => { const fileStream = fs.readFileSync(filePath); const uploadParams = { Bucket: bucket, ACL: "public-read", Body: fileStream, Key: filePath, ContentType: "image/png", }; console.log(filePath); const data = await s3.upload(uploadParams).promise(); console.log(data); return; };
请问这是什么原因?
原因分析
- 核心错误是流的方向用反了:
fs.createWriteStream的作用是创建一个写入本地文件的流,它的用途是把数据写入到指定路径的文件中,而非读取文件内容。当你把这个写流传给S3的Body参数时,这个流没有任何可读的数据,所以S3接收到空内容,最终生成0B的空文件。 fs.readFileSync是同步读取本地文件的API,它会直接返回文件的Buffer数据,S3的upload方法可以正确解析这个Buffer,因此能正常上传完整的图片内容。
解决方法
如果想用流的方式上传(适合大文件,避免内存占用过高),需要改用fs.createReadStream来创建读取本地文件的流,修改后的代码如下:
const uploadImage = async (filePath, fileId) => { // 替换为createReadStream读取本地文件 const fileStream = fs.createReadStream(filePath); const uploadParams = { Bucket: bucket, ACL: "public-read", Body: fileStream, Key: filePath, ContentType: "image/png", }; console.log(filePath); const data = await s3.upload(uploadParams).promise(); console.log(data); return; };
内容的提问来源于stack exchange,提问作者dthakurani
相关产品推荐
相关产品推荐

