尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Puter 云文件系统 puter.fs.mkdir() 目录创建 API 详解:参数语义、去重命名与父目录递归创建

Puter 云文件系统 puter.fs.mkdir() 目录创建 API 详解:参数语义、去重命名与父目录递归创建 Puter 云文件系统 puter.fs.mkdir() 目录创建 API 详解参数语义、去重命名与父目录递归创建【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puterputer.fs.mkdir()是 Puter 文件系统Puter FSJavaScript SDK 中用于在用户云端目录树中创建目录的核心接口它同时覆盖普通目录创建、同名去重、覆盖写、以及递归创建缺失父目录等实战场景。本文以 mkdir.md 为骨架结合 puter-js 前端实现、后端 FSController 与 FSService 源码完整还原该接口的语法、参数、返回值与错误语义让读者既能直接在网页、App、Node.js 与 Worker 中调用也能理解云端目录条目的真实创建过程。概览puter.fs.mkdir()允许调用方在用户自己的 Puter 文件系统中创建一个目录Directory。官方文档声明其支持平台为websites, apps, nodejs, workers也就是说在浏览器页面、Puter 应用、Node.js 进程以及 Puter Worker 中均可使用同一套 API。目录创建成功后调用方拿到的是一个描述该目录的FSItem对象可进一步读取其name、path等属性也可基于它继续执行子目录、文件操作。语法与三种调用形态mkdir支持位置参数与选项对象两种传参方式官方文档给出了三种等价写法puter.fs.mkdir(path) puter.fs.mkdir(path, options) puter.fs.mkdir(options)第一种形态只传目录路径字符串全部选项走默认值第二种形态路径 选项对象这是最常用的组合第三种形态只传一个选项对象此时目录路径必须写在options.path中。从源码看该操作由 operations/mkdir.js 中的defineOperation实现它把第一个位置参数声明为positional: [path]从而允许上面三种调用签名共存。SDK 内部还会把选项对象映射为后端/mkdir接口的请求体见下文底层链路章节。参数详解pathString必填要创建的目录路径。绝对路径以/或~/开头直接按云端完整路径解析例如~/Documents/projects相对路径会相对于当前 App 的根目录进行解析。从 getAbsolutePathForApp.js 可以看到当puter.appID存在时相对路径会被拼接为~/AppData/appID/path否则拼接为~/path同时该工具函数对 UUID 形态的输入会原样透传以便对已存在条目做直接寻址未传 path选项对象中也没有时SDK 默认按.当前工作目录处理。optionsObject官方文档支持的选项如下选项类型默认值说明pathString—目录路径。当路径未通过位置参数传入时用它指定要创建的目录overwriteBooleanfalse目标路径已存在且占用者不是目录时是否先删除占用者再创建目录dedupeNameBooleanfalse目标目录已存在时是否自动重命名去重如追加(1)、(2)createMissingParentsBooleanfalse是否递归创建缺失的父级目录类似mkdir -p此外在 SDK 类型定义FileSystem/types.js中还能看到两个兼容别名与扩展项renameBooleandedupeName的旧别名。前端请求构造时通过firstDefined(options, dedupeName, rename)取值即优先读dedupeName未定义再回退到renamerecursiveBooleancreateMissingParents的别名同样通过firstDefined(options, createMissingParents, recursive)回退取值shortcutToString可选的快捷方式目标用于创建指向已有条目的目录快捷方式。而真正的核心选项在 mkdir.js 中会被转换成后端的overwrite、dedupe_name、create_missing_parents等请求字段return { endpoint: /mkdir, body: { parent: path.dirname(absolutePath), path: path.basename(absolutePath), overwrite: options.overwrite ?? false, dedupe_name: firstDefined(options, dedupeName, rename) ?? false, shortcut_to: options.shortcutTo, // No socket at all for a client that opted out (puter.socketEnabled). original_client_socket_id: this.socket?.id, create_missing_parents: firstDefined(options, createMissingParents, recursive) ?? false, }, };注意这里的细节SDK 先把绝对路径拆成parent父目录与pathbasename 文件名两个字段再交给服务端因此空路径、根路径创建等边界情况由后端兜底拦截详见错误处理章节。返回值mkdir返回一个Promiseresolve 后的值是所创建目录对应的FSItem对象关于该对象模型的字段说明可查看 Objects/fsitem.md 文档页常用属性包括name、path、isDirectory等。目录创建后后端还会写入数据库条目kind: directory通过 socket 向 GUI/客户端广播新增条目事件#emitGuiItemAdded见 FSController.ts触发文件系统事件fs.create.directory见 FSService.ts供事件订阅方感知目录的新建。当目标目录已存在且未开启dedupeName时服务端会把它视为幂等成功并直接返回已存在目录的条目而不是报错详见 FSService 章节。完整示例下面三个示例来自官方文档分别演示基本创建、同名去重与父目录递归创建。示例采用完整 HTML 页面形式在浏览器中引用https://js.puter.com/v2/加载 SDK 即可运行。创建一个新目录html body script srchttps://js.puter.com/v2//script script // Create a directory with random name let dirName puter.randName(); puter.fs.mkdir(dirName).then((directory) { puter.print(${dirName} created at ${directory.path}); }).catch((error) { puter.print(Error creating directory:, error); }); /script /body /html示例借助puter.randName()生成随机目录名目录创建成功后从返回的FSItem中读取path打印实际创建位置失败时在catch中打印错误。同名去重创建目录html body script srchttps://js.puter.com/v2//script script (async () { // create a directory named hello let dir_1 await puter.fs.mkdir(hello); puter.print(Directory 1: ${dir_1.name}br); // create a directory named hello again, it should be automatically renamed to hello (n) where n is the next available number let dir_2 await puter.fs.mkdir(hello, { dedupeName: true }); puter.print(Directory 2: ${dir_2.name}br); })(); /script /body /html第一次创建hello成功第二次调用带上dedupeName: trueSDK 不会报冲突而是自动选取下一个空闲编号例如hello (1)并作为新目录的名称返回。递归创建缺失的父目录html body script srchttps://js.puter.com/v2//script script (async () { // Create a directory named hello in a directory that does not exist let dir await puter.fs.mkdir(my-directory/another-directory/hello, { createMissingParents: true }); puter.print(Directory created at: ${dir.path}br); })(); /script /body /html这里my-directory与another-directory此前并不存在。开启createMissingParents: true后SDK 会要求服务端一次性补齐中间层级最终创建出完整的.../my-directory/another-directory/hello返回条目的path即为最终落盘路径。底层原理从 JS SDK 到云端服务前端链路请求如何被构造前端入口在 operations/mkdir.js核心工作有三件路径归一化把相对路径换算为基于 App 根目录的绝对路径细节见前文参数部分路径拆分把绝对路径拆成parent与 basenamepath交给服务端的/mkdir接口选项规范化统一overwrite/dedupe_name/create_missing_parents字段并兼容rename、recursive等旧参数名。服务端路由权限与路径校验后端的mkdirEntry路由定义在 FSController.ts它挂在Post(/mkdir)上具备以下保护身份校验requireVerified: true要求调用者是已验证用户并走FS_MUTATE_LIMIT变更类限流路径归一化先解析~、折叠..、规整首尾/防止dirname推导父目录出错合法性校验空路径返回 400Missing path解析后路径等于根目录/时返回 400Cannot mkdir at root权限校验调用assertCanCreate检查创建权限若开启去重还会调用assertCanDedupeCreate去重命名本质上是在父目录内另起一个名字需要额外的创建许可。校验通过后调用services.fs.mkdir(...)并把落库得到的目录条目包装成对外安全的 v2 形态剔除id、parentId、userId等内部字段与能力 token返回给客户端。服务端语义FSService.mkdir 的四条分支真正决定目录创建语义的是 FSService.mkdir。其行为可用一个目标路径是否存在 选项组合的决策树概括目标路径状态dedupeNameoverwrite结果不存在任意任意直接创建目录已存在同名目录false任意幂等成功直接返回已有目录条目不报错已存在同名目录true任意通过#findDedupedName寻找下一个空闲名如hello (1)再创建已存在同名文件非目录falsefalse抛 409An entry already exists at path已存在同名文件非目录falsetrue先删除该文件非递归再原地创建目录已存在同名文件非目录true任意走去重改名逻辑实现中还有两个值得一提的工程细节父目录递归创建mkdir开头会先调用#resolveOrCreateParent在createMissingParents开启时逐级补齐父级目录并发竞态兜底由于存在性检查与INSERT 落库之间存在时间窗高并发下可能撞上数据库唯一键约束ER_DUP_ENTRY/SQLITE_CONSTRAINT。代码捕获该异常后回查主库若竞态赢家恰是目录则视为幂等成功返回它若不是目录才抛 409从而避免把底层ER_DUP_ENTRY泄漏成 500。错误处理速查调用puter.fs.mkdir()可能遇到的典型错误及其 HTTP 语义如下场景错误码说明请求体缺少path400Missing pathSDK 相对路径解析为空时也可能触发尝试在根目录/创建400Cannot mkdir at root根目录不允许被覆盖或重建目标被同名文件占用且未开overwrite/dedupeName409conflict提示An entry already exists at path无创建权限403 类权限错误由assertCanCreate/assertCanDedupeCreate抛出在实际业务代码中建议把 409 视为已存在类可恢复状态配合dedupeName或overwrite决策把 400 视为调用方参数缺陷及时修正调用参数。进阶用法与跨平台实践在 FSItem 上直接创建子目录mkdir并不只有puter.fs.mkdir一种入口。FSItem对象本身也提供了子目录创建方法见 FSItem.jsmkdir async function (name, autoRename false) { // Dont proceed if this is not a directory, throw error if ( ! this.isDirectory ) { throw new Error(mkdir() can only be called on a directory); } return puter.fs.mkdir(path.join(this.path, name), { dedupeName: autoRename }); };即拿到一个目录FSItem后可调用directory.mkdir(subdir)在其内部创建子目录当autoRename传true时等价于开启dedupeName。若当前条目本身不是目录调用会抛出mkdir() can only be called on a directory。这一入口非常适合在readdir/stat拿到条目后继续向下建目录的树形遍历场景。App 沙箱与桌面 GUI 场景在 PuterApp中运行有puter.appID相对路径默认落到~/AppData/appID/这一应用私有空间多个 App 之间天然隔离在桌面 GUIputer.env gui等场景下空路径会被原样透传避免破坏既有交互行为见 getAbsolutePathForApp.js。Node.js / Worker 与 CLI除了浏览器websites/apps同一 API 也适用于 Node.js 与 Puter Worker 环境。在命令行侧官方 CLI源码见 src/cli/src/commands/fs.js同样通过puter.fs.mkdir提供目录操作并习惯性地带上{ createMissingParents: true, dedupeName: false }组合来模拟mkdir -p语义其ensureRemoteDir工具函数在upload上传前会先确保远端目标根目录存在——这正说明递归创建父目录在真实工程里是高频刚需。与其他 FS API 配合目录创建通常是更复杂流程的第一步。官方文件系统文档集中与mkdir最常搭配的接口包括readdir.md创建后列出目录内容write.md / upload.md向新目录中写入文件stat.md校验条目创建结果delete.md递归清理不再需要的目录。总结puter.fs.mkdir()虽然形似一条简单的创建目录调用但在 Puter 云端文件系统里它完整承载了三层能力SDK 层的相对路径解析与参数规范化、控制器层的身份/限流/路径合法性校验以及服务层的覆盖写、幂等、去重与父目录递归补齐语义。理解了overwrite、dedupeName别名rename、createMissingParents别名recursive三者的取舍关系加上 400/403/409 的错误码认知你就可以在自己的网页、Puter App、Node.js 脚本与 Worker 中安全地构建多级目录结构而不必担心路径拼错或并发冲突。【免费下载链接】puter The Internet Computer! Free, Open-Source, and Self-Hostable.项目地址: https://gitcode.com/GitHub_Trending/pu/puter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表