VSCode扩展开发新建untitled文件保存时提示ENOENT错误如何解决
问题现象
开发VSCode扩展实现可编辑、可正常保存的新建文件功能,初始实现代码如下:
export async function linkA() { const newFile = Uri.parse('untitled:' + path.join(workspace.workspaceFolders![0].uri.path + "/templates", 'filename.txt')); workspace.openTextDocument(newFile).then(async document => { const edit = new WorkspaceEdit(); edit.insert(newFile, new Position(0, 0), "Hello world!"); return workspace.applyEdit(edit).then(success => { if (success) { window.showTextDocument(document); } else { window.showInformationMessage('Error!'); } }); });}
调用linkA函数时,可以正常打开名为filename.txt的新文件,也支持编辑文件内容,但执行保存操作时,VSCode弹出如下错误提示:
Failed to save 'filename.txt': Unable to write file '\c:\Users\RAM\Desktop\vscode-extension-samples\helloworld-sample\templates\filename.txt' (EntryNotFound (FileSystemError): Error: ENOENT: no such file or directory, open '\c:\Users\RAM\Desktop\vscode-extension-samples\helloworld-sample\templates\filename.txt')
故障原因
报错由两个问题共同导致:
- 手动拼接
untitled:协议和文件路径的写法存在跨平台兼容问题,Windows环境下会出现路径解析异常,生成的目标路径前多出非法反斜杠前缀,导致路径识别错误。 - 代码没有检查目标保存位置的
templates父目录是否存在,VSCode保存文件时不会自动递归创建不存在的父目录,目录缺失时直接写入文件就会触发ENOENT文件/目录不存在的错误。
修复方案
- 替换手动字符串拼接路径的逻辑,统一使用VSCode内置的
Uri.joinPathAPI处理路径拼接,自动适配Windows、macOS、Linux的路径格式,避免跨平台路径解析错误。 - 新建文件前先检查目标父目录是否存在,不存在则调用文件系统API递归创建对应目录,消除目录缺失导致的写入失败。
- 不要手动拼接
untitled:协议前缀,通过Uri对象的with方法指定协议为untitled,保证untitled临时文件和最终保存路径的正确关联。
修复后的完整代码如下:
import * as path from 'path'; import { Uri, workspace, window, WorkspaceEdit, Position } from 'vscode'; export async function linkA() { const workspaceRoot = workspace.workspaceFolders![0].uri; // 定位目标templates目录 const templatesDir = Uri.joinPath(workspaceRoot, 'templates'); // 检查目录是否存在,不存在则递归创建 try { await workspace.fs.stat(templatesDir); } catch (err) { await workspace.fs.createDirectory(templatesDir); } // 正确生成untitled类型的新文件Uri const targetFilePath = Uri.joinPath(templatesDir, 'filename.txt'); const newFile = targetFilePath.with({ scheme: 'untitled' }); const document = await workspace.openTextDocument(newFile); const edit = new WorkspaceEdit(); edit.insert(newFile, new Position(0, 0), "Hello world!"); const applySuccess = await workspace.applyEdit(edit); if (applySuccess) { await window.showTextDocument(document); } else { window.showInformationMessage('创建新文件失败'); } }
内容的提问来源于stack exchange,提问作者Witaek
相关产品推荐
相关产品推荐

