You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:40:49