使用NestJS+Socket.io+Angular上传文件时fs writeFile报EISDIR错误
文件上传报错 EISDIR 原因分析与修复方案
错误信息
Error: EISDIR: illegal operation on a directory, open 'CDN/attachments/63aea8c5e37c6b1242a6973f/63aea86fe37c6b1242a6970a/20230112140045/' at Object.openSync (node:fs:584:3) at writeFileSync (node:fs:2201:35) at C:\Users\alms\Desktop\Chatenium2\chatenium-server\src\chat\message\dm\dm.service.ts:87:26 at Array.forEach (<anonymous>) at Socket.<anonymous> (C:\Users\alms\Desktop\Chatenium2\chatenium-server\src\chat\message\dm\dm.service.ts:74:20) at Socket.emit (node:events:513:28) at Socket.emitUntyped (C:\Users\alms\Desktop\Chatenium2\chatenium-server\node_modules\socket.io\dist\typed-events.js:69:22) at C:\Users\alms\Desktop\Chatenium2\chatenium-server\node_modules\socket.io\dist\socket.js:614:39 at processTicksAndRejections (node:internal/process/task_queues:77:11)
问题原因
核心问题是你尝试向目录路径写入文件,而非指定具体的文件路径:
- 前端传入的
filesDest是带结尾斜杠的目录路径:${this.chatid}/${this.userData.userid}/${dateX}/ - 后端循环处理文件时,先创建了这个目录,随后直接用该目录路径调用
writeFileSync,但writeFileSync要求传入具体文件名,不能是目录,因此触发EISDIR错误。 - 额外问题:循环内重复执行目录创建逻辑,虽不会报错,但属于冗余操作。
修复代码
修改后端NestJS代码:
// 先统一创建目标目录,移到循环外避免重复执行 const destDir = `CDN/attachments/${data.filesDest}`; function mkdirRecursiveSync(path: string) { if (!existsSync(path)) { mkdirRecursiveSync(dirname(path)); mkdirSync(path); } } mkdirRecursiveSync(destDir); // 循环处理每个文件,为每个文件指定具体文件名 data.files.forEach((file, index) => { // 优先使用文件原始名称,无原始名称则用索引+时间戳生成唯一文件名 const fileName = file.name || `uploaded_file_${index}_${Date.now()}`; const fullFilePath = `${destDir}/${fileName}`; writeFileSync(fullFilePath, file); });
关键说明
- 目录创建逻辑前置:将目录创建代码移到循环外,仅执行一次,提升性能。
- 指定具体文件名:结合目录路径与文件名生成完整文件路径,确保
writeFileSync操作的是文件而非目录。 - 避免文件覆盖:使用文件原始名称或结合索引、时间戳生成唯一文件名,防止同目录下文件被覆盖。
内容的提问来源于stack exchange,提问作者Almaszosz
相关产品推荐
相关产品推荐

