ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

learnyounode 实战:使用 fs.readdir 与 path.extname 实现按扩展名过滤目录文件

learnyounode 实战:使用 fs.readdir 与 path.extname 实现按扩展名过滤目录文件 教程CLI【免费下载链接】learnyounodeLearn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.项目地址https://gitcode.com/gh_mirrors/le/learnyounode点击查看免费下载本篇技术指南以 learnyounodeNode.js 自导式编程练习的filtered_ls练习为核心完整讲解如何编写一个接收「目录路径 文件扩展名」两个命令行参数、异步列出并过滤目录文件的小程序。读完本文你将掌握process.argv的参数解析、fs.readdir()的异步回调用法、path.extname()的扩展名匹配技巧并理解该练习内置的自动化校验机制如何从源码层面强制你使用异步 I/O。练习目标一行一文件按扩展名过滤本练习要求你新建一个名为filtered-ls.js的文件编写一个程序打印出指定目录下的文件列表并以指定的扩展名过滤。程序运行时会被传入两个参数第一个参数目录路径例如/path/to/dir/第二个参数扩展名例如txt。核心行为要求如下若第二个参数是txt则只输出那些以.txt结尾的文件注意第二个参数不会自带开头的.需要你自行拼接过滤后的结果逐行打印到控制台每个文件名占一行必须使用异步 I/O这是本练习的硬性约束也是校验的焦点。同时需要留意一个新手常见误区程序的第一个命令行参数并不是process.argv数组的第一项——Node 会为系统信息预留前两个位置process.argv[0]是 Node 可执行文件路径process.argv[1]是正在执行的脚本路径因此真正的用户参数从process.argv[2]开始。核心 APIfs.readdir 与 path.extnamefs.readdir()异步读取目录fs.readdir()方法接收两个参数第一个是路径名pathname第二个是回调函数。回调签名固定为function callback (err, list) { /* ... */ }其中list是包含目录中所有文件名字符串的数组。完整的fs模块文档见仓库内的 docs-nodejs/fs.html。path.extname()提取文件扩展名path模块的extname()方法接收一个文件名或路径返回其扩展名字符串包含开头的点号。例如path.extname(learnyounode.txt)返回.txt。完整的path模块文档见 docs-nodejs/path.html。由于用户传入的第二个参数不带.而extname()的返回值带.因此正确的比较方式是把参数手动拼接成. ext后再与extname()的结果比对。直接拿ext path.extname(file)比较会永远不相等这是本练习最常见的一个坑。参考实现solution/solution.js仓库官方参考答案位于 exercises/filtered_ls/solution/solution.js其完整实现如下use strict const fs require(fs) const path require(path) const folder process.argv[2] const ext . process.argv[3] fs.readdir(folder, function (err, files) { if (err) return console.error(err) files.forEach(function (file) { if (path.extname(file) ext) { console.log(file) } }) })逐行拆解这段代码的关键点参数提取process.argv[2]为目录process.argv[3]为扩展名在提取时即拼接为. ext后续直接与path.extname()比较避免了每次循环都重复拼接。异步回调fs.readdir的回调先统一处理err——一旦出错立即console.error(err)并return防止空数组导致的连锁报错。过滤输出用files.forEach遍历目录列表仅当path.extname(file)严格等于目标扩展名时才console.log(file)实现「每个匹配文件一行」的输出格式。测试目录中的另一个合法实现 test/filtered_ls/valid_01.js 则采用了list.filter(...).forEach(...)的函数式写法效果等价const fs require(fs) const path require(path) fs.readdir(process.argv[2], function (err, list) { if (err) { console.log(err) } list.filter(function (file) { return path.extname(file) . process.argv[3] }).forEach(function (file) { console.log(file) }) })验证方式使用 verify 命令写完filtered-ls.js后在终端中运行以下命令检查程序是否正确$ learnyounode verify filtered-ls.js在仓库实际命令行中{appname}对应的就是learnyounode命令仓库入口见 learnyounode.js。运行verify时练习框架会在系统临时目录下创建测试目录路径形如_learnyounode_pid依据 exercises/filtered_ls/file-list.json 中定义的 15 个文件写入测试数据其中包含learnyounode.txt、data.json、README.md、words.dat等不同扩展名的文件以及md、dat这类没有.前缀的裸文件名专门用来检验你的过滤逻辑对边界情况的处理以testDir和md作为两个参数分别传入你的提交脚本与参考实现最后调用验证处理器给出判定。源码级校验机制异步 I/O 是如何被强制检查的本练习最特别之处在于「必须使用异步 I/O」不只是一句提示而是被自动化校验强制执行的硬性规则。这一点可以从 exercises/filtered_ls/exercise.js 的实现细节中证实。1. 打桩监控 fs 调用wrapexercise.js 第 19 行通过exercise.wrapModule(require.resolve(../my_first_io/wrap))加载了打桩模块 exercises/my_first_io/wrap.js。该模块在提交脚本运行前会遍历fs、fs.promisesfsp与util上的所有方法并逐一替换为包装函数同时借助调用栈$captureStack判断 fs 调用是否发生在用户主程序mainProgram中。凡是从用户代码发起的fs.readdir、fs.readdirSync等调用都会被记录进ctx.fsCalls集合以方法名为键、调用次数为值随后调用原始函数继续真实执行。2. 同步 vs 异步的判定与打分verify processorexercise.js 第 5372 行定义了仅在verify模式下生效的验证处理器。它的判定逻辑非常直接遍历exercise.wrapData.fsCalls中记录的所有被调用的 fs 方法名若方法名以Sync结尾如readdirSync判定为使用了同步 I/O触发fail.sync否则判定为异步调用触发pass.async若完全没有调用任何 fs 方法既无同步也无异步同样判定失败fail.unused这是为了应对提交脚本根本不使用 fs、侥幸通过的其他路径最终结果由usedAsync !usedSync决定必须用到了异步方法且没有任何同步调用才算通过。也就是说即使程序逻辑正确、输出结果完全一致只要用了fs.readdirSync也会被判失败。这一点同样体现在测试用例上目录 test/filtered_ls/ 中的 invalid_01.js 就是一份「逻辑正确但使用readdirSync」的典型反例用来验证校验器能正确将其拦截。3. 其他不合规路径调用外部命令test/filtered_ls/invalid_02.js 展示了一种绕道式实现通过child_process.exec(ls -1 dir)调用系统命令来获取文件列表。虽然它也用了异步的exec但这种方案既不使用fs.readdir也不使用path.extname且极易受平台和目录名中的空格影响属于教学上不推荐的实现方式。从源码结构可推断的测试数据设计意图exercises/filtered_ls/file-list.json 中的 15 个文件名不是随意挑选的它们覆盖了若干边界场景文件名考察点learnyounode.txt、w00t.txt常规.txt目标扩展名的正常匹配learnyounode.dat、words.dat、w00t.dat、data.dat其他扩展名应被过滤掉api.html、README.md、CHANGELOG.md、LICENCE.md非目标扩展名的排除md、dat不带点号的裸文件名path.extname(md)返回空字符串不可能匹配.md考验过滤逻辑的健壮性data.json、wrrrrongdat干扰项其中wrrrrongdat的扩展名陷阱以dat结尾但无点号前缀专治依赖endsWith(dat)的草率实现这从侧面印证了正确的过滤方式必须基于path.extname()返回值与. ext的严格相等比较而不是简单的字符串结尾匹配例如file.endsWith(ext)后者会把wrrrrongdat这样的文件错误地当成.dat文件输出。延伸迈向下一练习 make_it_modularfiltered_ls的进阶版是make_it_modular练习——把同样的过滤逻辑抽取成独立模块只接收(dir, filterStr, callback)并回调错误优先的callback参考实现见 exercises/make_it_modular/solution/solution_filter.jsuse strict const fs require(fs) const path require(path) module.exports function (dir, filterStr, callback) { fs.readdir(dir, function (err, list) { if (err) { return callback(err) } list list.filter(function (file) { return path.extname(file) . filterStr }) callback(null, list) }) }该模块与本文的过滤核心逻辑完全同源区别仅在于错误通过callback(err)上抛而不是直接console.error体现了 Node.js 错误优先error-first回调的模块化约定是复用与测试的关键前提。小结通过filtered_ls这一练习你需要带走四项核心能力正确理解process.argv的偏移规则从第 2 个下标开始取用户参数熟练使用fs.readdir(path, callback)的异步回调模式并坚持「回调第一行处理 err」的防御式写法用path.extname()配合. 扩展名做精确过滤避免字符串结尾匹配的陷阱理解本练习的自动化校验原理——它通过包装 fs 方法、解析调用栈来判断你用的是readdir还是readdirSync从而将「异步 I/O」从口头规范落实为可执行的硬性检查。这些能力将直接复用到后续的make_it_modular、http_client等练习中构成学习 Node.js 异步编程与模块化设计的基础一环。赞分享教程CLI【免费下载链接】learnyounodeLearn You The Node.js For Much Win! An intro to Node.js via a set of self-guided workshops.项目地址https://gitcode.com/gh_mirrors/le/learnyounode点击查看免费下载相关推荐learnyounode 第二关使用 fs.readdir 与 path.extname 实现按扩展名过滤文件列表learnyounode 第二关使用 fs.readdir 与 path.extname 实现按扩展名过滤文件列表 导读 本篇文章以 learnyounode教程CLI3步实现多语言视频本地化KrillinAI智能翻译配音完整方案3步实现多语言视频本地化KrillinAI智能翻译配音完整方案 在全球化内容传播的时代多语言视频制作已成为刚需。KrillinAI是一款基于AI大模型的视频教程CLIlearnyounode 实战用 fs.readdir 与 path.extname 实现按扩展名过滤的目录列表FILTERED LS 详解learnyounode 实战用 fs.readdir 与 path.extname 实现按扩展名过滤的目录列表FILTERED LS 详解 导读 本文以教程CLI上一篇如何将普通3D打印机升级为5轴系统终极完整指南下一篇zram-generator与传统交换分区谁更适合你的Linux系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表