一个命令行工具实例

这个实例包含了处理进程中的stdinstdout相关的api,以及文件系统有关的api,使用回调和事件机制来实现并发,主要锻炼基于非阻塞事件的I/O编程中的流控制。

// 声明模块依赖
const fs = require('fs');
// 这里使用我发布的的一个工具函数做打印工具
const print = require('idiv-utils').print; // 存储stat, 避免handleUserInput再次fs.stat
const stats = [];
const EXIT = 'exit';
const GREETING = '\nEnter your choose index or \'exit\' '; const printGreeting = function(GREETING, color) {
var colorNum = Number(color);
process.stdout.write('\033' + `[${ isNaN(colorNum) ? 90 : colorNum }m` + GREETING + '\033[39m');
}; // 遍历完根目录后执行的函数
const readFile = function readFile(files) {
process.stdin.setEncoding('utf8');
process.stdin.resume();
printGreeting(GREETING); process.stdin.on('data', function(data) {
handleUserInput(data, files);
});
}; const handleFile = function file(i, files) {
var fileName = files[i];
fs.stat(process.cwd() + '/' + fileName, function(err, stat) {
// 暂不处理错误 return 掉
if (err) return;
stats[i] = stat;
// 调用stat.isDirectory判断是否为目录
const printArgs = stat.isDirectory() ? [fileName + '--是目录', 96] : [fileName + '--是文件', 93];
print(...printArgs); if (++i === files.length) {
return readFile(files);
} else {
// 递归调用file直至遍历完所有子文件和目录
return file(i, files);
}
});
}; // 用户输入选择后会触发process.stdin的data事件, 这是该事件的间接回调
const handleUserInput = function handleUserInput(data, files) {
if (data.toString().trim() === EXIT) {
// 后面没有io事件时, node会自动退出
process.stdin.pause();
process.stdin.removeAllListeners();
return print('Good bye, welcomne next use!');
} var fileName = files[Number(data)];
if (!fileName) {
printGreeting(data.toString().trim() + '不存在', 91);
printGreeting(GREETING);
} else {
// 定位用户所选文件的绝对路径
const path = __dirname + '/' + fileName;
if (stats[Number(data)].isDirectory()) {
fs.readdir(path, function(err, data) {
if (err) return;
print(fileName + '目录下有: ' + data.length + '文件');
data.forEach(function(file) {
print('-- ' + file);
});
printGreeting(GREETING);
});
} else {
fs.readFile(path, function(err, data) {
print(data.toString().replace(/\s+/g, ''), 90);
printGreeting(GREETING);
});
}
}
}; // 读取根目录
fs.readdir(process.cwd(), function(err, files) {
// 暂不处理错误
if (err) return; handleFile(0, files);
});

最新文章

  1. ASP.NET MVC之Session State性能问题(七)
  2. input(file)按钮美化
  3. java 读文件路径问题
  4. swift中的结构体和枚举
  5. Strategy策略模式
  6. Maven错误在这里看【项目无法成功编译由于maven未成功下载依赖导致】
  7. DBA_Oracle Erp加密和解密账户密码(案例)
  8. C/C++ 内联函数
  9. 解决CAS单点登录出现PKIX path building failed的问题
  10. .Net Framework 4.0安装cmd命令
  11. SpringMVC接收复杂集合参数
  12. osgi实战学习之路:8. Service-3之ServiceTracker
  13. C# 通过GUID生成不重复的ID
  14. Python·——进程1
  15. python安装Jieba中文分词组件并测试
  16. hdu 4864 任务分配贪心
  17. Linux内核分析--内核中的数据结构双向链表【转】
  18. Day22-Django之Form组件验证
  19. HTML文档的经常使用标记
  20. 二、 Mosquitto 使用说明

热门文章

  1. es6 Object.assign(target, ...sources)
  2. springboot扫描自定义的servlet和filter代码详解_java - JAVA
  3. org.hibernate.NonUniqueObjectException 原因及解决办法
  4. c++ copy和operator =
  5. 19. ClustrixDB 执行计划解读
  6. 南京网络赛 E K Sum
  7. Pyhton实用的format()格式化函数
  8. modern php笔记---2.1、特性(命名空间、特性、性状)
  9. What's the difference between HEAD^ and HEAD~ in Git?
  10. linux下挂载磁盘