示例工程【免费下载链接】vscode-extension-samplesSample code illustrating the VS Code extension API.项目地址https://gitcode.com/gh_mirrors/vs/vscode-extension-samples点击查看免费下载导读本文基于 VS Code 官方扩展样例仓库vscode-extension-samples中的 nodefs-provider-sample讲解如何通过vscode.workspace.registerFileSystemProvider注册一个自定义 URI schemedatei://的文件系统提供者把磁盘上的真实目录以自定义协议的形式挂载进 VS Code 工作区。读完本文你将掌握FileSystemProvider接口全部方法的实现要点、Node.jsfsAPI 与 VS Code 文件系统错误模型的映射方式以及如何编写.code-workspace文件让自定义协议目录被资源管理器正常打开与编辑。样例概览用 Node.js 桥接磁盘与 VS Codenodefs-provider-sample/README.md 对样例的定位只有一句话A sample extension that implements a file system provider for the schemedatei://using node.js FS APIs即基于 Node.js 文件系统 API为datei://这个自定义 scheme 实现一个文件系统提供者。与同仓库的 fsprovider-sampleMemFS纯内存文件系统不同本样例不维护任何内存树而是把datei://的 URI 直接映射到本地磁盘路径通过uri.fsPath透传给 Node.js 的fs模块完成真实读写。这意味着资源管理器里datei://目录下看到的就是磁盘上真实存在的文件编辑器打开、修改、保存文件最终都会落盘它演示了自定义协议 真实存储的组合方式适合作为远程/虚拟文件系统实现前的参照。整个样例只有一个源码文件 nodefs-provider-sample/src/extension.ts约 300 行外加 package.json、tsconfig.json 与 ESLint 配置。快速上手通过 .code-workspace 挂载 datei:// 目录README 给出的 Setup 只有两步但这是理解整个机制的关键入口创建一个.code-workspace文件其中包含一个使用datei://scheme 指向本地磁盘目录的文件夹条目在 VS Code 中打开该 workspace 文件。示例配置如下README 原文{ folders: [ { uri: datei://full absolute path to folder on disk } ] }要点说明datei是扩展注册的自定义 scheme见下文激活代码uri字段必须完整填写磁盘上某个绝对路径VS Code 在解析多根工作区时会依据该 scheme 找到已注册的FileSystemProvider并调用其readDirectory/stat等方法填充资源管理器若打开 workspace 后资源管理器为空或报错优先检查扩展是否已安装并激活、datei://后路径是否正确、目标目录是否有访问权限。激活与注册onFileSystem:datei 与 registerFileSystemProvider1. 激活事件声明扩展的激活时机在 nodefs-provider-sample/package.json 中声明activationEvents: [ onFileSystem:datei ]onFileSystem:scheme是 VS Code 为文件系统提供者准备的特殊激活事件当 VS Code 首次遇到datei://开头的 URI例如解析 workspace 或尝试打开该协议下的文件时才会激活本扩展。这与记忆中的激活事件一样采用懒加载避免扩展常驻后台。2. 注册提供者入口函数 nodefs-provider-sample/src/extension.ts#L12-L16 只有一次调用export function activate(_context: vscode.ExtensionContext) { vscode.workspace.registerFileSystemProvider(datei, new DateiFileSystemProvider(), { isCaseSensitive: process.platform linux }); }registerFileSystemProvider(scheme, provider, options)的三个参数含义scheme自定义协议名这里是datei与激活事件、workspace URI 前缀三者必须完全一致provider实现vscode.FileSystemProvider接口的实例options.isCaseSensitive告知 VS Code 该文件系统是否大小写敏感。样例按平台决定——Linux 上为true其他平台Windows/macOS为false以匹配对应文件系统的真实行为避免补全、重命名等操作出现误判。注意返回的Disposable未显式加入context.subscriptions从代码结构看注册后即随扩展生命周期生效工程上通常建议把返回的 disposable 放进context.subscriptions以便随扩展停用自动注销。FileSystemProvider 接口的完整实现DateiFileSystemProvidernodefs-provider-sample/src/extension.ts#L18-L132实现了接口要求的所有方法watch、stat、readDirectory、createDirectory、readFile、writeFile、delete、rename以及变化通知事件onDidChangeFile。1. 变化通知onDidChangeFile 与 watch提供者内部持有一个EventEmitterFileChangeEvent[]并通过onDidChangeFile暴露给 VS CodeL20-L28这是资源管理器/编辑器感知外部文件变化的唯一通道。watchL30-L45直接委托 Node.js 的fs.watchwatch(uri: vscode.Uri, options: { recursive: boolean; excludes: string[]; }): vscode.Disposable { const watcher fs.watch(uri.fsPath, { recursive: options.recursive }, async (event, filename) { if (filename) { const filepath path.join(uri.fsPath, _.normalizeNFC(filename.toString())); // TODO support excludes (using minimatch library?) this._onDidChangeFile.fire([{ type: event change ? vscode.FileChangeType.Changed : await _.exists(filepath) ? vscode.FileChangeType.Created : vscode.FileChangeType.Deleted, uri: uri.with({ path: filepath }) } as vscode.FileChangeEvent]); } }); return { dispose: () watcher.close() }; }实现细节值得注意事件类型推断change事件映射为Changed其余事件如rename再通过_.exists(filepath)判断是Created还是Deleted文件名在 mac 上先经过normalizeNFC归一化详见下文平台小节再拼接绝对路径options.excludes目前未实现源码留有TODO注释计划用 minimatch 库支持排除规则recursive直接透传给fs.watch返回的 disposable 负责关闭 watcher实现接口的取消监听语义。2. 元数据与目录读取stat / readDirectorystat通过lstatstat组合实现_.statLinkL240-L257先用fs.lstat判断是否为符号链接若是则再用fs.stat获取目标信息从而把符号链接这个元信息保留下来交给FileStat处理见下文。readDirectoryL56-L70逐个对子项调用_stat返回[name, FileType]数组供资源管理器渲染目录树。3. 读写与目录创建readFile / writeFile / createDirectoryreadFileL76-L78直接fs.readFile返回BuffercreateDirectoryL72-L74使用mkdirp支持一次性创建多级目录writeFileL80-L99完整实现create/overwrite语义async _writeFile(uri: vscode.Uri, content: Uint8Array, options: { create: boolean; overwrite: boolean; }): Promisevoid { const exists await _.exists(uri.fsPath); if (!exists) { if (!options.create) { throw vscode.FileSystemError.FileNotFound(); } await _.mkdir(path.dirname(uri.fsPath)); } else { if (!options.overwrite) { throw vscode.FileSystemError.FileExists(); } } return _.writefile(uri.fsPath, content as Buffer); }即文件不存在时必须create: true否则抛FileNotFound文件已存在时必须overwrite: true否则抛FileExists。这是与 VS Code 内部写入约定保持一致的关键——编辑器另存为、资源管理器新建文件都会携带对应的 options 标志。4. 删除与重命名delete / renamedeleteL101-L107recursive: true时用rimraf递归删除目录树否则用fs.unlink删除单个文件/空目录renameL109-L129处理覆盖与目标父目录不存在的情况——目标已存在且不允许覆盖时抛FileExists允许覆盖则先递归删除旧目标目标父目录不存在时先mkdirp创建最后fs.rename。5. 待办与扩展点源码在 L131 留有注释可用 Node.js 8.x 新增的fs.copy方法实现更快的copy()优化路径。这说明FileSystemProvider是可选的copy方法为 VS Code 提供更高效的复制能力当前样例未实现VS Code 会退化为readFile writeFile方式完成复制。错误模型把 Node.js 错误码映射为 FileSystemErrorNode.js 的错误ENOENT、EISDIR等与 VS Code 的文件系统错误模型并不一致。样例在_.messageErrornodefs-provider-sample/src/extension.ts#L152-L170中做了统一映射Node.js errnoVS Code FileSystemErrorENOENT文件/目录不存在FileNotFound()EISDIR对目录执行了文件操作FileIsADirectory()EEXIST目标已存在FileExists()EPERM/EACCES权限不足NoPermissions()其他原样抛出所有fs回调都经handleResultL144-L150包装出错时调用messageError转成 VS Code 语义的错误对象。只有抛出FileSystemError类型的错误VS Code 才会在 UI 层给出恰当的中文/本地化提示并正确处理文件未找到等场景。FileStatfs.Stats 到 vscode.FileStat 的桥接FileStat 类 将fs.Stats包装为vscode.FileStat提供type按符号链接/文件/目录计算vscode.FileType——符号链接使用FileType.SymbolicLink | FileType.Directory或File的位或组合其余按isFile/isDirectory判定都不满足则为UnknownisFile/isDirectory/isSymbolicLink便捷判断size/ctime/mtime时间戳毫秒级来自fs.Stats。注意mtime/ctime在符号链接场景下的取值以最终stat结果为准这为依赖时间戳的增量同步类扩展提供了准确依据。平台细节大小写敏感与 Unicode 归一化两个平台相关处理体现了工程严谨性大小写敏感注册时isCaseSensitive: process.platform linux——Linux 文件系统通常区分大小写Windows/macOS 不区分NFC 归一化_.normalizeNFCL178-L190仅当process.platform darwin时执行String.prototype.normalize(NFC)。macOS 的 HFS/APFS 在存储时往往把文件名归一为 NFD而 VS Code 内部使用 NFC导致fs.watch回调中拿到的文件名可能与 URI 不一致归一化后再拼路径可避免文件变化了却找不到对应 URI的问题。构建、运行与调试在仓库根目录下进入样例目录执行cd nodefs-provider-sample npm install npm run compile相关脚本定义在 nodefs-provider-sample/package.json#L23-L28compiletsc -p ./按 tsconfig.jsonCommonJS 模块、ES2024 目标、开启strict与noUnusedLocals编译到out/watchtsc -watch -p ./开发时增量编译vscode:prepublish发布打包前自动执行npm run compile。依赖方面运行时仅需要mkdirp与rimraf两个包package.json#L29-L32开发依赖包含types/vscode^1.100.0即引擎最低要求 VS Code 1.100.0package.json#L13-L15。lint 使用 ESLint 9 typescript-eslint 8见 eslint.config.mjs。调试时按 F5 启动 Extension Development Host再打开你准备好的.code-workspace文件即可在资源管理器中看到datei://目录并正常进行新建、编辑、保存、删除、重命名等操作。关联样例从提供者到消费者理解本样例的最佳参照物是同仓库的另外两个样例fsprovider-sampleMemFS同样是FileSystemProvider的完整实现但数据存于内存scheme 为memfs适合对比内存态与磁盘态实现差异其截图见 fsprovider-sample/sample.pngfsconsumer-sample不实现提供者而是以消费者身份通过vscode.workspace.fsstat/readFile/writeFile/readDirectory对任意提供者的文件系统做统一读写例如用uri.with({ path })派生新 URI、统计目录文件总大小。三者合起来构成完整闭环provider 决定文件从哪来、怎么存consumer 用统一的workspace.fsAPI 消费无需关心底层是磁盘、内存还是自定义协议。这正是 VS Code 文件系统抽象层的设计意图。小结nodefs-provider-sample 用不到 300 行代码演示了一个可直接落盘的自定义文件系统提供者从datei://scheme 的注册、.code-workspace挂载到FileSystemProvider全方法实现、Node.js 错误码到FileSystemError的映射、FileStat元数据桥接再到 macOS NFC 归一化与 Linux 大小写敏感等平台细节覆盖了实现生产级文件系统扩展所需的核心知识点。对于需要接入远程文件、云盘或自定义存储的扩展作者这是一个极具参考价值的起点。赞分享示例工程【免费下载链接】vscode-extension-samplesSample code illustrating the VS Code extension API.项目地址https://gitcode.com/gh_mirrors/vs/vscode-extension-samples点击查看免费下载相关推荐Redis for Windows终极安装配置指南5分钟快速部署高性能缓存服务Redis for Windows终极安装配置指南5分钟快速部署高性能缓存服务 Redis for Windows是Redis官方版本的原生Windows移植数据库KV存储缓存awspec插件生态扩展测试能力的8个实用工具推荐awspec插件生态扩展测试能力的8个实用工具推荐 awspec是一款专为AWS资源打造的RSpec测试框架能够帮助开发者轻松编写和执行AWS资源的测试用例Node.js文件系统事件聚合使用node-fs-extra实现复合事件Node.js文件系统事件聚合使用node fs extra实现复合事件 在Node.js开发中文件系统操作往往涉及多个步骤和事件如创建目录、复制文件、写开发工具上一篇如何永久保存微信聊天记录面向普通用户的完整数据留痕方案下一篇如何永久保存微信聊天记录本地免费工具WeChatMsg完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
RHEL 8更换yum源 1、关闭官方订阅在配置文件中关闭这个官方的订阅 编辑配置文件“ 更改参数“ enabled 1”到“ enabled 0”root用户修改配置文件以下内容:
vim /etc/yum/pluginconf.d/subscription-manager.conf
[main] enabled02、将 Red Hat 官方订阅删除yum remove subscr… · 2026/9/24 13:53:04
PaddleSpeech WaveFlow 数据预处理深度解析:从 LJSpeech 原始音频到对数 Mel 频谱与训练数据集 人工智能语音音频NLP媒体生成 【免费下载链接】PaddleSpeech Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation … · 2026/9/24 13:53:04
Chat2DB 上手指南:自然语言生成 SQL,统一管理 16+ 数据库 Chat2DB 上手指南:自然语言生成 SQL,统一管理 16 数据库 【免费下载链接】Chat2DB Chat2DB is a free, cross-platform, local-first database client and SQL workspace for developers, DBAs, analysts, and data teams. Connect to 40 databases, man… · 2026/9/24 13:53:04
TCNOpen 源码编译与 TRDP 协议通信测试实战指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 3:55:43
Apereo CAS Surrogate 认证之 JSON 账户存储配置实战指南 后端认证鉴权单点登录 【免费下载链接】cas Apereo CAS - Identity & Single Sign On for all earthlings and beyond. 项目地址: https://gitcode.com/gh_mirrors/ca/cas 点击查看 免费下载 Surrogate 认证(又称模拟/代管认证,即“Web … · 2026/9/25 3:55:37
pylibcudf 的 ORC 读写 API 完全指南:从 read_orc 到分块写入 数据分析数据工程机器学习 【免费下载链接】cudf cuDF - GPU DataFrame Library 项目地址: https://gitcode.com/gh_mirrors/cu/cudf 点击查看 免费下载 本篇技术指南以 cuDF 仓库中 pylibcudf 的 ORC(Optimized Row Columnar)格式 I/O 模块… · 2026/9/25 3:55:37
学生时间管理APP全栈开发实战:课程表、番茄钟与数据闭环设计 带过三年毕设项目,被问得最多的一个选题就是“学生时间管理APP”。很多同学第一反应是这个题目太老——课程表、待办事项、番茄钟,网上一抓一大把模板,还能做出什么花来?这话只对了一半。时间管理工具确实不稀奇,但面向… · 2026/9/25 3:55:31
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37