将随机生成文件名的图片上传至AWS S3存储桶——路径指定问题
解决Puppeteer截图自动上传AWS S3的问题
问题根源
fs.createReadStream不支持glob通配符(**),直接传入screenshots/**/**/**/*.png会被当成单个文件名,自然触发“文件不存在”的错误。必须先通过glob工具匹配出所有符合条件的具体文件路径,再逐个处理上传。
解决方案步骤
- 安装
glob库处理文件路径匹配 - 匹配所有目标截图文件
- 遍历文件列表,逐个上传到S3,同时保留原有目录结构
修正后的代码
import { PutObjectCommand } from "@aws-sdk/client-s3"; import { s3Client } from "../libs/s3Client.js"; import path from "path"; import fs from "fs"; import { glob } from "glob"; // 引入glob库 // 匹配所有screenshots子目录下的png文件,返回绝对路径避免相对路径混乱 const getScreenshotFiles = async () => { return glob("../../screenshots/**/*.png", { absolute: true }); }; // 单个文件上传至S3的函数 const uploadFileToS3 = async (filePath) => { // 提取相对于screenshots目录的路径,作为S3存储的Key,保留日期目录结构 const relativePath = path.relative("../../screenshots", filePath); const uploadParams = { Bucket: "bucket-name", Key: relativePath, // 示例:"2024/05/20/randomname.png" Body: fs.createReadStream(filePath), }; try { const data = await s3Client.send(new PutObjectCommand(uploadParams)); console.log(`文件 ${filePath} 上传成功`, data); return data; } catch (err) { console.error(`文件 ${filePath} 上传失败`, err); throw err; } }; // 批量上传入口函数 export const run = async () => { try { const files = await getScreenshotFiles(); if (files.length === 0) { console.log("未找到任何截图文件"); return; } // 并行上传所有文件,若需顺序上传可改用for...of循环 await Promise.all(files.map(file => uploadFileToS3(file))); console.log("所有截图上传完成"); } catch (err) { console.error("批量上传出错", err); } }; run();
关键说明
- glob匹配逻辑:
glob("../../screenshots/**/*.png")会递归扫描所有子目录下的PNG文件,{ absolute: true }确保返回绝对路径,避免不同运行环境下的相对路径问题。 - S3目录结构保留:通过
path.relative提取相对于screenshots的路径作为S3的Key,让云端存储结构和本地一致,方便后续按日期查找截图。 - 依赖安装:执行
npm install glob安装所需的路径匹配库。
内容的提问来源于stack exchange,提问作者Evan Parker
相关产品推荐
相关产品推荐

