使用JavaScript从S3获取文件后如何正确保存原格式文件?
解决S3下载二进制文件保存后体积过大的问题
问题根源是你用transformToString()处理JPG这类二进制流——这个方法会把原始字节按UTF-8编码转成字符串,破坏了二进制数据的结构,导致文件体积异常增大且无法正常打开。下面是两种正确保存原始格式文件的方案:
方法1:流管道写入(推荐大文件)
直接把S3返回的ReadableStream通过管道写入文件,无需将整个文件加载到内存:
const { createWriteStream } = require('fs'); const { pipeline } = require('stream/promises'); const run = async () => { try { const data = await s3Client.send(new GetObjectCommand(bucketParamsGet)); const outputStream = createWriteStream('./testfile.jpg'); // 记得添加正确的文件后缀 // 使用stream.promises.pipeline自动处理流的错误与关闭 await pipeline(data.Body, outputStream); console.log('文件保存成功'); } catch (err) { console.log("Error", err); } }; run();
方法2:转Buffer后写入(适合小文件)
将流转换成Buffer再写入磁盘:
const fs = require('fs/promises'); // 使用Promise版本的fs模块 const run = async () => { try { const data = await s3Client.send(new GetObjectCommand(bucketParamsGet)); // 将ReadableStream转换为二进制Buffer const buffer = await data.Body.transformToByteArray(); await fs.writeFile('./testfile.jpg', buffer); console.log('文件保存成功'); } catch (err) { console.log("Error", err); } }; run();
额外注意两个细节:
- 你原代码里
await fs.writeFile(...)搭配回调函数是错误的,回调版本的fs.writeFile不返回Promise,await不会生效,改用fs.promises.writeFile即可。 - 保存时务必加上对应文件后缀(比如
.jpg),否则系统无法识别文件类型。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

