免费获取学习方案
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点击查看免费下载导读本篇技术指南围绕 learnyounode 练习 FILTERED LS按扩展名过滤目录文件展开以 exercises/filtered_ls/problem.it.md英文原版 problem.md为核心骨架。你将掌握如何编写一个接收「目录路径 扩展名」两个命令行参数、使用 Node.js 异步 I/O 打印指定扩展名文件列表的 CLI 程序并理解 learnyounode 校验器如何从源码层判断你是否真正使用了异步 API。读完本文你既能独立完成该练习也能通过仓库源码与测试用例反向验证自己的实现思路。练习目标读懂任务本身官方对本题的描述非常紧凑核心要求可以拆解为四条两个命令行参数程序运行时接收两个参数——第一个是目录路径例如/path/to/dir/第二个是需要过滤的文件扩展名例如txt。过滤规则第二个参数不带前缀.程序需要把它拼成.txt只输出文件名以.txt结尾的文件。输出格式过滤后的文件列表逐行打印到控制台一行一个文件名。强制异步必须使用异步 I/O使用同步 API 会被判为失败校验逻辑见下文「校验器如何工作」一节。英文原版 problem.md 还额外补充了一条新手极易踩坑的说明命令行参数并非process.argv数组的前两个值——数组前两项被 Node 保留用于系统信息process.argv[0]是 node 可执行文件路径process.argv[1]是脚本路径真正的自定义参数从process.argv[2]开始。核心 APIfs.readdir()与path.extname()fs.readdir(path, callback)异步读取目录练习提示给出了fs.readdir()的用法第一个参数是路径名第二个参数是回调函数回调签名如下function callback (err, list) { /* ... */ }其中list是文件名字符串组成的数组。err在读取失败如目录不存在、权限不足时非空。完整用法示例const fs require(fs) fs.readdir(/path/to/dir, function (err, list) { if (err) return console.error(读取目录出错:, err) console.log(目录中共有 %d 个文件, list.length) // list 形如 [a.txt, b.md, c.js, ...] })fs模块的完整文档见仓库中的 docs-nodejs/fs.html。需要特别强调的是fs.readdir()是异步方法它不会阻塞事件循环回调会在 I/O 完成后的某个事件循环 tick 中被调用这正是本题「必须使用异步 I/O」所要求的 API 形态。path.extname(file)提取文件扩展名path模块的extname方法返回路径中最后一部分的扩展名包括开头的点号例如const path require(path) path.extname(index.html) // .html path.extname(index.) // . path.extname(index) // path.extname(.index) // path.extname(data.txt) // .txtpath模块的完整文档见 docs-nodejs/path.html。由于extname返回的扩展名自带.前缀而练习的第二个参数不带.因此比较时需要手动拼接. process.argv[3]。完整可运行的参考实现标准解法两层循环写法仓库 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) } }) })实现要点const folder process.argv[2]与const ext . process.argv[3]读取两个自定义参数并提前给扩展名补上.前缀。fs.readdir(folder, callback)异步读取目录内容。回调内先用console.error(err)处理错误分支再遍历files用path.extname(file) ext精确匹配扩展名命中即console.log(file)逐行输出。use strict严格模式是本仓库所有代码的统一风格见 exercises/filtered_ls/exercise.js 首行保持与仓库一致的代码习惯有利于通过 lint 类检查。函数式解法filter forEach 链式写法测试用例 test/filtered_ls/valid_01.js 展示了一种更简洁的写法——用Array.prototype.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) }) })两种写法在功能上等价选择取决于个人风格核心都是「异步读目录 path.extname精确比较 逐行打印」。校验器如何工作从源码看懂「必须异步」的判定逻辑learnyounode 对该练习的自动校验远不止「运行结果对不对」它会在源码调用层面检测你是否用了同步 API。相关逻辑分布在三处1. 测试环境搭建exercise.jsexercises/filtered_ls/exercise.js 负责构造校验环境在系统临时目录创建_learnyounode_pid测试目录依据 exercises/filtered_ls/file-list.json 中定义的文件清单生成 15 个测试文件包括learnyounode.dat、learnyounode.txt、api.html、README.md、md、data.json、w00t.dat、w00t.txt、wrrrrongdat、dat等——注意其中既有扩展名合法的文件也有像wrrrrongdat这样扩展名奇怪的干扰项通过this.submissionArgs.unshift(md)和this.submissionArgs.unshift(testDir)把「测试目录路径 md扩展名」注入到待测程序的process.argv中即在目录中过滤出所有.md文件校验完成后用rimraf清理临时目录。2. fs 调用追踪wrap.jsexercises/my_first_io/wrap.js 是关键的运行时探针它把fs模块以及fs.promises、util上的同名方法的所有方法用代理包装通过$captureStack捕获调用栈判断调用是否来自被测主程序。凡是被测程序直接调用的 fs 方法都会被记录到ctx.fsCalls计数表中且以Sync结尾的方法如readdirSync与异步方法如readdir会被分开统计。3. 判定规则Sync 即失败回到 exercises/filtered_ls/exercise.js 中的addVerifyProcessor判定逻辑非常直接遍历wrapData.fsCalls方法名匹配/Sync$/就立即判fail提示fail.sync命中的异步方法则记pass若既没用同步也没用异步方法同样判fail提示fail.unused最终通过条件为usedAsync !usedSync。也就是说只要你在程序里调用了任何fs.xxxSync无论运行结果是否正确都会被判定为失败。这一点与 test/filtered_ls/invalid_01.js 中刻意使用fs.readdirSync的反例遥相呼应——该测试正是「同步实现必挂」的实证。另外 test/filtered_ls/invalid_02.js 展示了另一种反面实现调用外部命令ls -1并配合child_process.exec拼接结果。它虽然也是异步的但并未使用fs.readdir()同样不符合题目对fsAPI 的考核意图。验证命令与运行方式完成filtered-ls.js后按英文原版 problem.md 的说明运行校验$ learnyounode verify filtered-ls.js校验器会自动传入构造好的测试目录与md扩展名运行你的程序并核对输出。也可以用learnyounode run filtered-ls.js先手动试跑自行传入真实目录与扩展名例如$ learnyounode run filtered-ls.js /tmp txt自查清单自定义参数从process.argv[2]、process.argv[3]读取而非从数组头部读取扩展名比较时补上前缀. process.argv[3]或path.extname(file) . ext使用fs.readdir()异步回调里先处理err再遍历list只用path.extname()判断扩展名不要手写file.endsWith(. ext)等字符串方案后者虽然结果可能正确但偏离了练习对path模块的引导逐行输出一个文件占一行。延伸思考从本题到真实工程fs.readdir() 扩展名过滤是「目录扫描」「文件分发」「静态资源索引」等日常任务的底层原语。在真实工程中同样的模式通常还会叠加递归子目录改用fs.readdir后递归进入子目录或使用fs.promises.readdirasync/await串行化遍历过滤条件扩展从单一扩展名扩展到多扩展名集合、排除隐藏文件等批量处理在回调中结合stream或Promise.all对命中文件做异步批处理。理解本题的「异步 回调 精确比较」三步结构是后续练习如juggling_async、make_it_modular等的基础也是学习 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 实现按扩展名过滤的异步目录列表filtered_ls 练习详解learnyounode 实战使用 fs.readdir 与 path.extname 实现按扩展名过滤的异步目录列表filtered_ls 练习详解 本教程CLIlearnyounode 实战用 fs.readdir() path.extname() 实现按扩展名过滤的目录文件列表filtered_ls 练习详解learnyounode 实战用 fs.readdir path.extname 实现按扩展名过滤的目录文件列表filtered_ls 练习详解 这篇教程CLIlearnyounode 实战使用 fs.readdir 与 path.extname 编写按扩展名过滤的目录列表程序learnyounode 实战使用 fs.readdir 与 path.extname 编写按扩展名过滤的目录列表程序 本篇技术指南围绕 learnyouno教程CLI上一篇终极指南如何用OptiScaler免费解锁游戏超高清画质支持XeSS/FSR2/3的DLSS替代神器下一篇GOODBYEADS开发工具链推荐提升规则维护效率的软件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表