S3文件下载异常:含冒号的PNG文件仅存为0KB无扩展名文件求助
问题原因与解决方法
核心问题
你遇到的问题是Windows文件系统不允许文件名包含冒号(:)。当代码尝试写入名为anthi:_anti_hair_thinning_hair_spray.png的文件时,Windows会自动截断文件名到冒号前的部分(即anthi),同时因为fs.writeFileSync没有错误捕获机制,写入失败后静默生成了0KB的空文件。
解决方案
需要对S3返回的文件名进行特殊字符清理,替换掉Windows(以及跨平台)不允许的字符,同时添加错误捕获避免静默失败。
修改后的代码片段
const objects = await s3.listObjectsV2(listParams).promise(); for (const object of objects.Contents) { if (object.Size >= MIN_FILE_SIZE_IN_BYTES) { const fileKey = object.Key; const fileExtension = path.extname(fileKey).toLowerCase(); if (allowedFileExtensions.includes(fileExtension)) { try { const originalFileName = path.basename(fileKey); // 替换所有跨平台不允许的文件名特殊字符为下划线 const sanitizedFileName = originalFileName.replace(/[:\\/*?"<>|]/g, '_'); const localFilePath = path.join(localDownloadFolder, sanitizedFileName); const data = await s3.getObject({ Bucket: bucketName, Key: fileKey }).promise(); fs.writeFileSync(localFilePath, data.Body); console.log(`File downloaded to: ${localFilePath}`); } catch (err) { console.error(`Failed to download file ${object.Key}:`, err); } } } }
关键修改点
- 文件名清理:用正则表达式
/[:\\/*?"<>|]/g匹配所有Windows文件系统禁止的字符,替换为下划线_,确保文件名在所有平台都合法。 - 错误捕获:添加
try-catch块包裹文件写入逻辑,能及时发现并打印下载/写入过程中的错误,避免静默失败。
额外说明
如果你的运行环境是类Unix系统(Linux/macOS),冒号是允许的,但为了代码的跨平台兼容性,统一清理特殊字符仍然是最佳实践。
内容的提问来源于stack exchange,提问作者Abhinav
相关产品推荐
相关产品推荐

