开发工具【免费下载链接】node-fs-extraNode.js: extra methods for the fs object like copy(), remove(), mkdirs()项目地址https://gitcode.com/gh_mirrors/no/node-fs-extra点击查看免费下载ensureFile(file[, callback])是 node-fs-extra 提供的确保文件存在工具方法目标文件不存在时创建若父目录缺失则一并递归创建已存在时原样保留、绝不修改。本文以 docs/ensureFile.md 为骨架结合仓库源码 lib/ensure/file.js、别名导出 lib/ensure/index.js 与测试用例 lib/ensure/tests/create.test.js完整覆盖 API 签名、回调 / Promise / async-await 三种调用方式、同步变体以及底层实现原理读完后你可以在任何需要幂等触碰文件touch 语义的场景中直接落地使用。一、核心语义什么是 ensureFileconst fs require(fs-extra) fs.ensureFile(/tmp/this/path/does/not/exist/file.txt)ensureFile的行为可以用一句话概括官方文档原文语义文件不存在→ 创建该文件文件所处的目录不存在→ 递归创建这些目录后再创建文件文件已存在→不做任何修改NOT MODIFIED连文件内容、时间戳都保持不变。这与原生fs.writeFile有本质区别fs.writeFile会直接写入覆盖目标文件而ensureFile是幂等确保存在等价于 Unix 下的touch语义但更强大——它还会顺带补齐缺失的目录链。对应同步变体为ensureFileSync(file)语义完全一致只是以同步方式执行详见 docs/ensureFile-sync.md。API 签名ensureFile(file[, callback])参数类型说明fileString要确保存在的文件路径callbackFunction可选。完成或出错时调用回调参数(err)err为ErrorensureFileSync(file)参数类型说明fileString要确保存在的文件路径别名AliasensureFile的别名为createFileensureFileSync的别名为createFileSync。在 lib/ensure/index.js 中可以看到二者被显式绑定为同一实现module.exports { createFile, createFileSync, ensureFile: createFile, ensureFileSync: createFileSync // ... }二、三种异步调用方式官方文档 docs/ensureFile.md 给出了完整示例以下逐一展开。1. 回调风格Callbackconst fs require(fs-extra) const file /tmp/this/path/does/not/exist/file.txt fs.ensureFile(file, err { console.log(err) // null // file has now been created, including the directory it is to be placed in })回调只接收一个err参数成功时为null失败时携带Error。注意err为null不代表文件是新创建的——文件可能本来就存在这一点与NOT MODIFIED语义一致。2. Promise 风格fs.ensureFile(file) .then(() { console.log(success!) }) .catch(err { console.error(err) })不传回调时ensureFile返回一个 Promise成功时 resolve不携带值失败时 reject 出错误对象。3. async/await 风格async function example (f) { try { await fs.ensureFile(f) console.log(success!) } catch (err) { console.error(err) } } example(file)三种风格底层是同一套实现。从源码看lib/ensure/file.js 的异步版本通过universalify的fromPromise包装module.exports { createFile: u(createFile), createFileSync }也就是说异步实现本质上是一个 async 函数再被包装成既可回调、又可 Promise的通用 API因此三种写法可以随意混用在同一项目中。同步变体示例const fs require(fs-extra) const file /tmp/this/path/does/not/exist/file.txt fs.ensureFileSync(file) // file has now been created, including the directory it is to be placed inensureFileSync成功时无返回值失败时直接抛出异常适合在脚本初始化、构建工具等同步流程中使用。三、底层实现原理逐行拆解ensureFile的完整异步实现位于 lib/ensure/file.js其执行流程可分四步async function createFile (file) { let stats try { stats await fs.stat(file) } catch { } if (stats stats.isFile()) return // ① 已存在且是普通文件 → 直接返回 const dir path.dirname(file) let dirStats null try { dirStats await fs.stat(dir) } catch (err) { if (err.code ENOENT) { // ② 父目录不存在 → 递归创建并写文件 await mkdir.mkdirs(dir) await fs.writeFile(file, ) return } else { throw err } } if (dirStats.isDirectory()) { // ③ 父目录是目录 → 直接写文件 await fs.writeFile(file, ) } else { await fs.readdir(dir) // ④ 父路径被文件占据 → 触发 ENOTDIR } }关键设计点解读① 先 stat 再决定幂等的核心第一步用fs.stat(file)探测目标文件。如果 stat 成功且stats.isFile()为真直接return——不写文件、不改内容这是已存在文件 NOT MODIFIED语义的源码级保证。注意fs.stat失败如 ENOENT时被空catch吞掉随后继续向下执行创建流程。② ENOENT 分支递归创建目录如果fs.stat(dir)抛出的错误码是ENOENT父目录不存在则调用mkdir.mkdirs(dir)递归创建整个目录链然后fs.writeFile(file, )以空内容创建文件。这里的mkdirs就是文档中ensureDir/mkdirp的同一实现见 lib/mkdirs/index.js它在 lib/mkdirs/make-dir.js 中通过fs.mkdir(dir, { mode, recursive: true })完成recursive: true正是整条目录链一次性建好的关键默认 mode 为0o777。③ 父目录已存在直接写文件若父目录 stat 成功且是目录则直接fs.writeFile(file, )创建文件。④ 父路径被文件占据抛 ENOTDIR若父路径 stat 成功但不是目录比如/tmp/a.txt是个文件而你要确保/tmp/a.txt/b.txt存在代码故意调用fs.readdir(dir)目的就是让底层抛出ENOTDIR错误——这是一个利用系统调用报错的巧妙技巧可以给出清晰而非模棱两可的错误提示。同步实现的结构差异同步版本 lib/ensure/file.js 逻辑相同但把先探测目录合并进了 try/catchfunction createFileSync (file) { let stats try { stats fs.statSync(file) } catch { } if (stats stats.isFile()) return const dir path.dirname(file) try { if (!fs.statSync(dir).isDirectory()) { fs.readdirSync(dir) // 父路径非目录 → 触发 ENOTDIR } } catch (err) { if (err err.code ENOENT) mkdir.mkdirsSync(dir) // 目录缺失 → 递归创建 else throw err } fs.writeFileSync(file, ) }它先尝试statSync(dir)并检查是否为目录非目录则走readdirSync抛ENOTDIRstat 失败且错误码为ENOENT则mkdirsSync(dir)补齐目录链最后统一writeFileSync(file, )。由于同步 API 没有u()包装它直接以普通函数导出。四、测试用例佐证三种核心行为仓库测试 lib/ensure/tests/create.test.js 对异步与同步两个版本分别验证了三个核心行为与文档语义完全对应文件与目录都不存在时创建文件构造TEST_DIR/随机目录/随机.txt路径断言创建后fs.existsSync(file)为真异步测试见 L22-L31同步见 L61-L68。文件已存在时不修改先用fs.writeFileSync(file, hello world)写入内容再调用createFile断言读取结果仍为hello world异步见 L34-L44同步见 L70-L77。目录树中间节点是文件时报 ENOTDIR让existingFile是一个已存在的文件再把目标路径拼在其下path.join(existingFile, 随机.txt)断言错误码err.code ENOTDIR异步见 L46-L56同步见 L79-L91。这三组用例正好对应上一节源码的 ①②③④ 四条路径说明文档行为有完整的自动化测试保障。五、与 ensureDir 的配合及典型应用场景ensureFile依赖的mkdirs正是文档 docs/ensureDir.md 中讲解的ensureDir/mkdirp同一实现它支持传入 modeconst fs require(fs-extra) const dir /tmp/this/path/does/not/exist fs.ensureDirSync(dir, 0o2775) // Integer 即 mode fs.ensureDirSync(dir, { mode: 0o2775 }) // Object 形式等价不过需要注意ensureFile自身不接受 mode 参数创建出的目录/文件使用默认权限目录0o777文件由writeFile()按 umask 决定。如果你的场景需要精确控制目录权限建议先ensureDir(dir, { mode })再ensureFile(file)组合使用。典型应用场景包括日志文件的幂等初始化应用启动时ensureFile(logPath)重复启动不会清空或覆盖已有日志配置文件占位首次运行生成空配置文件用户已编辑过则保留原内容缓存/临时文件目录预热先ensureDir建目录再ensureFile放占位文件测试夹具准备像仓库测试那样在beforeEach中emptyDircreateFile构造干净的临时文件结构。六、注意事项与边界路径必须为字符串file参数类型为String传入其他类型会导致底层 fs 调用报错。不覆盖已有内容这是最容易被误解的一点——ensureFile不是创建并写入它只保证存在已有文件内容、权限、时间戳均保持不变。错误场景父路径被普通文件占据时会收到ENOTDIR权限不足时可能收到EACCES/EPERM路径非法时可能收到EINVAL。异步版本通过回调err或 Promise reject 暴露这些错误。环境要求当前仓库 package.json 声明engines.node 14.14mkdirs依赖 Node.js 原生fs.mkdir(recursive: true)请确保运行环境满足要求。ESM 使用仓库同时提供 ESM 入口 lib/esm.mjs在import环境下可通过import fs from fs-extra使用同样的 API。七、总结ensureFile(file[, callback])以极简的 API 封装了stat 探测 → 递归建目录 → 空内容写文件 → 已存在则跳过的完整幂等流程并通过universalify同时支持回调、Promise 与 async/await 三种风格。无论是自动补齐父目录的便捷性还是已存在绝不修改的安全性它都是 Node.js 文件系统初始化场景中最值得优先使用的工具方法之一。结合本文源码分析与测试证据你现在可以在自己的项目中放心地用它替代手写的目录检查 文件创建样板代码。延伸阅读同一ensure家族还包括ensureDirdocs/ensureDir.md、ensureLinkdocs/ensureLink.md、ensureSymlinkdocs/ensureSymlink.md它们与ensureFile一起通过 lib/ensure/index.js 统一导出到fs-extra顶层 API。赞分享开发工具【免费下载链接】node-fs-extraNode.js: extra methods for the fs object like copy(), remove(), mkdirs()项目地址https://gitcode.com/gh_mirrors/no/node-fs-extra点击查看免费下载相关推荐node-fs-extra 的 emptyDirSync() 深度指南一步清空目录并保留目录本身node fs extra 的 emptyDirSync 深度指南一步清空目录并保留目录本身 导读 fs extra 是 Node.js 生态中广受欢迎的 f开发工具深入理解node-fs-extra的copySync方法文件与目录同步复制指南深入理解node fs extra的copySync方法文件与目录同步复制指南 前言 在Node.js开发中文件系统操作是常见的需求。原生fs模块虽然功能强开发工具Klipper 故障排查全流程指南用日志分析一次修好 3 类高频故障Klipper 故障排查全流程指南用日志分析一次修好 3 类高频故障 打印头走了三个小时突然停住控制台弹出报错料头废掉。对 Klipper 用户来说3D嵌入式智能硬件工业制造创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
Android+XAMPP+MySQL家校互动平台:环境搭建与联调实战 简介:这是一份面向Android开发学习者与毕业设计/课程设计人员的家校互动平台项目资料,基于Android客户端、XAMPP服务端与MySQL数据库实现,采用CS架构完成家校通知、成绩查询、互动留言等核心功能,适用于相关项目设计及Android与服… · 2026/9/25 5:59:14
天猫复购预测高分代码复现:特征工程与LightGBM调参避坑指南 简介:这是一份基于阿里天池大赛学习赛的天猫复购预测完整案例,面向需要完成期末大作业、课程设计或入门数据挖掘的 Python 学习者。项目涵盖数据下载与预处理、特征工程、模型训练与测试全流程,代码注释详尽,新手也能读懂并快速复… · 2026/9/25 5:59:14
Atlas 300V 24G推理卡部署YOLO全解析:从架构到实站 很多人第一次搜“atlas”的时候,其实心里是有点懵的。查了一圈,一会儿看到Atlas 200 DK开发套件,一会儿看到Atlas 300V推理卡,一会儿又跳出来Atlas 800训练服务器,名字全带Atlas,定位却完全不一样。尤其是最… · 2026/9/25 5:59:14
Atlas 300V 24G部署YOLO目标检测实战与踩坑记录 最近手头项目正好用上 Atlas 300V 24G 这张卡,前前后后折腾了一轮 YOLO 部署。从驱动安装到模型转换,再到最后的推理调优,踩了不少坑,也总结出一些规律。趁热把整个过程记录下来,给准备在 Atlas 系列加速卡上做目标检测… · 2026/9/25 7:19:20
树形论坛系统:基于PHPWind的层级回复架构与性能优化实践 /* 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 7:19:20
FAST Color PixelBlob 接口完全指南:像素数据的统一抽象与量化应用 前端UI组件 【免费下载链接】fast The adaptive interface system for modern web experiences. 项目地址: https://gitcode.com/gh_mirrors/fa/fast 点击查看 免费下载 PixelBlob 是 microsoft/fast-colors 颜色工具库中定义的一个核心接口,用于统一抽… · 2026/9/25 7:19:20
PaddleSpeech FastSpeech2 VCTK 多说话人语音合成实战:从数据准备到模型部署全流程解析 人工智能语音音频 【免费下载链接】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 and Keyword… · 2026/9/25 7:19:20
2024年网络安全人才报告解读:薪资四档、人才缺口与AI冲击 简介:《2024年网络安全产业人才发展报告》是一份全面解析网络安全人才市场的行业调研资料,适合政府决策者、企业管理者、教育机构、网络安全从业者及高校学生参考,帮助各方把握人才供需现状、薪酬水平与AI技术带来的变革。压缩包内为PDF格式&… · 2026/9/25 7:19:08
创维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