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

Node.js中fs.readdir与readFile无回调版本查询及目录文件上传S3实现

问题解答

Node.js的fs模块官方原生提供了无需回调的同类方法,完全可以适配你的使用场景:

无回调方法说明

  • 读取目录对应方法:fs.promises.readdir(path[, options]),直接使用await调用即可返回目录下的文件名称数组,无需传入回调函数
  • 读取文件对应方法:fs.promises.readFile(path[, options]),同样支持await调用直接返回文件内容
    你也可以用Node.js内置的util.promisify工具手动把原有回调式方法转成Promise风格,但更推荐直接使用官方封装好的fs.promises系列方法,兼容性和稳定性更好。

适配你场景的优化后可运行代码

你原来的代码存在逻辑缺陷:虽然给readFiles1加了async标识,但内部还是用回调写法,外部的await readFiles1不会等待内部读目录、读文件、上传操作全部完成就会继续执行。优化后代码如下:

const fs = require('fs').promises // 直接引入Promise版本的fs接口
const path = require('path') // 用path拼接路径避免跨平台兼容问题
const AWS = require('aws-sdk')
const express = require('express')
const app = express()

const s3Upload = async (req, res) => {
  const directoryName = "MAXIS_GAMING/Daily/"
  try {
    await readFiles1(directoryName)
    res.send('所有文件上传完成')
  } catch (err) {
    console.error('处理流程出错:', err)
    res.status(500).send('上传失败:' + err.message)
  }
}
  
const readFiles1 = async(dirname) => {
  // await读取目录
  const files = await fs.readdir(dirname)
  console.log('目录下文件列表:', files.join(' '))

  // 批量生成读文件+上传的异步任务
  const uploadTasks = files.map(async (filename) => {
    const fullFilePath = path.join(dirname, filename)
    // await读取文件内容
    const content = await fs.readFile(fullFilePath, 'utf-8')
    console.log('读取文件完成:', filename)
    // await执行上传
    await uploadFiles(filename, content)
  })
  // 等待所有文件上传完成
  await Promise.all(uploadTasks)
}
  
const uploadFiles = async (fileName, fileContent) => {
  console.log('开始上传文件:', fileName)
  const GLOBAL_ACCESS_KEY_ID = 'AKIDAQWZX6B3XUBDIFHLPC5LYFTJF15XPIQ';
  const GLOBAL_SECRET_ACCESS_KEY = 'Sv4Fe4h4QgErG5XoZbgeC63oczkdW3bMQfC0jvyR8bPbJ9Y97k+'
  const GLOBAL_DEFAULT_REGION = 'ap-southeast-1';
  const S3_IMAGE_BUCKET ='max-stg-image/stage/reports'
    
  AWS.config.update({
    accessKeyId: GLOBAL_ACCESS_KEY_ID,
    secretAccessKey: GLOBAL_SECRET_ACCESS_KEY,
    region: GLOBAL_DEFAULT_REGION,
  });
    
  const s3 = new AWS.S3()
  const params = {
    Bucket: S3_IMAGE_BUCKET,
    Key: fileName,
    Body: fileContent
  };
  
  // 将回调式的s3.upload封装为Promise风格支持await
  return new Promise((resolve, reject) => {
    s3.upload(params, function(err, data) {
      if (err) return reject(err);
      console.log(`文件上传成功: ${data.Location}`);
      resolve(data)
    });
  })
}

app.get('/home/s3Upload', s3Upload)

// 自行补充服务启动逻辑即可,如:app.listen(3000, () => console.log('服务启动'))

优化说明

  • 所有异步操作都支持同步等待,解决了你原来代码中await不生效的问题
  • 统一用try/catch捕获全局异常,不需要在每个回调里单独处理错误
  • 用path模块拼接路径,避免斜杠漏写、跨平台路径分隔符不兼容的问题
  • 如果目录下文件较多不想并发太高,可以把Promise.all替换为普通for循环逐个执行,控制并发量

内容的提问来源于stack exchange,提问作者krishna kurtakoti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:18:03