个人项目WC.exe Node.js+electron实现
前言
实现语言:Javascript
编译工具:webstorm
GitHub:https://github.com/NPjuan/WC.git
项目要求
wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:
wc.exe [parameter] [file_name] (由于网络原因,打包工具暂时无法下载,未能实现打包成exe文件,所以需求模式目前未能完成,只能通过GUI模式,如需使用命令行需按如下方式)
node wc.js <filePath>
其中<filePath>
为可选参数,可以为相对路径或绝对路径,相对路径即相对根据wc.js所在的路径
基本功能列表:
功能 | 实现情况 |
---|---|
返回文件 file.txt 的字符数) | 已实现 |
返回文件 file.txt 的词的数目) | 已实现 |
返回文件 file.txt 的行数 | 已实现 |
递归处理目录下符合条件的文件 | 已实现 |
返回更复杂的数据(代码行 / 空行 / 注释行) | 实现注释行 |
调用GUI完成上述功能 | 已实现 |
空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”。
代码行:本行包括多于一个字符的代码。
注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面加注释:
} //注释
在这种情况下,这一行属于注释行。
解题思路
由于个人对JS语言较熟悉的原因,使用了JS来编写本题,对题目的理解为调用读取文件的api并利用正则表达式返回需要的数据,这里需要在node环境下执行,又由于需要打包成exe文件执行,则需要安装electron作为开发,可惜electron打包工具下载了N次依然下载失败,目前使用命令行的方式需要变为node wc.js <filePath>
设计实现过程
- 调用node.js的api来实现读取文件
- 先解决对单独文件的分析
- 使用正则表达式匹配
- 先去除各种标点符号作为干扰,如
name,
- 将部分缩写变为全写,如
this's --> this is
- 清除无意义的换行,空行
- 区分普通单词和在注释里的单词,将其分开
- 获取单词,字母,行数等等
- 先去除各种标点符号作为干扰,如
- 通过递归调用,读取文件夹内的文件,再复用上述过程
- 对于单独文件之间输出,对于文件夹则先将数组扁平化再输出
代码说明
主要功能代码 wc.js
executor
函数为主入口函数,参数可选绝对路径或相对路径或不选,返回值为文件或文件夹的详细信息
analyise
函数为文本分析函数,返回文本的详细信息
ergodicDirSync
为文件夹分析函数,返回值类型为数组,包含文件夹内所有符合文件类型的文本信息对象
const fs = require('fs');
const path = require('path')
// 当前目录下绝对地址
// process.argv 第一个参数为执行路径,第二个为参数
// 获取选择的路径
// 分析文件夹
function ergodicDirSync(filePath) {
try {
// 获取当前路径下的所有文件
let arr = []
let result = fs.readdirSync(filePath)
result.forEach((fileName) => {
// 获取文件的绝对地址 如果是 node_modules 则排除在外
if (fileName === 'node_modules') {
return
}
let fileDir = path.join(filePath, fileName)
let fileStatus = fs.statSync(fileDir)
// 如果是文件而非目录 // 匹配 txt js
if (fileStatus.isFile() && fileName.match(/.[txt|js]$/g)) {
arr.push(analysisFileSync(fileDir))
} else if (fileStatus.isDirectory()) {
// 递归
arr.push(ergodicDirSync(fileDir))
} else {
console.log(`${fileName} 文件格式不符合要求`)
}
})
return arr
} catch (e) {
console.warn(e)
return arr
}
}
// 分析文件
function analysisFileSync(filePath) {
let context = fs.readFileSync(filePath, 'utf-8')
let result = analysis(context)
result.filePath = filePath
return result
}
// 读取文件
function readFile(filePath){
return new Promise((resolve, reject)=>{
fs.readFile(filePath, 'utf-8', (err, file) => {
if ( err ) {
reject(err)
}
resolve(file)
})
})
}
// 文件文本分析
function analysis(context) {
let time = new Date()
if (context.length === 0) {
return {
pureWords: 0,
pureLetters: 0,
words: 0,
lines: 0,
letters: 0,
notes: 0,
multilineComment: 0,
'time': new Date()-time,
code: 0
}
}
// 清除缩写,例如 Here's // 清除标点符号
let pureText = context.replace(/'s/gm, ' is').replace(/[^\s\/\*\w\u4e00-\u9fa5]/gm, '')
// 获取单词数,不含中文
let words = pureText.match(/[a-zA-Z0-9_$]+/gm)
// 获取字母
let letters = pureText.match(/\w/gm)
// 获取行数并清除无意义的换行,这里必须用到context否则如果一行文本只有标点符号会被忽略
let lines = context.split(/\r\n/gm).filter((item)=>{
return item !== ''
})
// 获取单行注释
let notes = lines.map(temp => {
if (temp.match(/\/\/[^\n]*/)) {
return temp.match(/\/\/[^\n]*/)[0]
} else {
return ''
}
}).filter((item)=>{
return item !== ''
})
// 获取多行注释 使用 *?非贪婪模式
let multilineComment = pureText.match(/(\/\*)(.|\n|\r)*?(\*\/)/gm)
// 获取注释以外的单词
// 第一个 replace 除去单行注释 //
// 第二个 replace 除去多行注释 /**/
let pureWords = pureText.replace(/\/\/[^\n]*/gm,'').replace(/(\/\*)(.|\n|\r)*?(\*\/)/gm,
'').match(/[a-zA-Z0-9_$]+/gm)
// 获取注释以外的字母
let pureLetters = pureText.replace(/\/\/[^\n]*/gm,'').replace(/(\/\*)(.|\n|\r)*?(\*\/)/gm,
'').match(/\w/gm)
return {
pureWords: pureWords?pureWords.length:0,
pureLetters: pureLetters?pureLetters.length:0,
words: words?words.length:0,
lines: lines?lines.length:0,
letters: letters?letters.length:0,
notes: notes?notes.length:0,
multilineComment: multilineComment?multilineComment.length:0,
'time': new Date()-time,
code: 1
}
}
// 默认为当前路径
function executor(curFilePath = path.resolve(''), platform = 1) {
// 如果是从node.js 附带参数命令启动
if (process.argv[2] && platform) {
// 如果传递的是根路径
if (process.argv[2].match(/^[a-zA-Z]+:/g)) {
curFilePath = process.argv[2]
} else {
// 否则传递的是相对路径
curFilePath = ((curPath, dir)=>{
let pos = curPath.lastIndexOf('\\')
return path.join(curPath.slice(0, pos),dir?dir:'')
})(process.argv[1], process.argv[2])
}
console.log(curFilePath)
}
let result = undefined
let fileStatus = fs.statSync(curFilePath)
if (fileStatus.isFile()) {
console.log('你选择了文件')
result = analysisFileSync(curFilePath)
} else if (fileStatus.isDirectory()) {
console.log('你选择了文件夹')
result = ergodicDirSync(curFilePath)
}
console.log(result)
return result
}
主函数 main.js 调用GUI
let electron = require('electron')
let app = electron.app
let BrowserWindow = electron.BrowserWindow
let mainWindow = null
app.on('ready', ()=>{
mainWindow = new BrowserWindow({
width: 800,
height: 800,
webPreferences: {
nodeIntegration: true
}
})
mainWindow.loadFile('./index.html')
mainWindow.on('closed', ()=>{
mainWindow = null
})
})
测试运行
命令行模式无参数模式
命令行带参数模式
GUI
GUI多文件
其中pureWords是排除在注释内的单词,pureLetters同理
项目小结
本次项目用了很多以前不曾用过或者用的很少的知识和工具,在复习和学习新技术上使用了较多的时间,所以明白了笔记的重要性,可以快速的复习,平时需要注重积累。对于新知识的学习需要明白自己最需要的是什么,单刀直入,不在一些细枝末节浪费时间,先快速开发,能用再说,后续再回头看
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 15 | 15 |
· Estimate | ·预估这个任务需要多少时间 | 15 | 15 |
Development | 开发 | 550 | 1025 |
· Analysis | · 需求分析(包括学习新技术) | 180 | 210 |
· Design Spec | · 生成设计文档 | 20 | 20 |
· Design Review | · 设计复审(和同事审核设计文档) | 0 | 0 |
· Coding Standard | · 代码规范(为目前开发制定合适的规范) | 0 | 0 |
· Design | · 具体设计 | 20 | 40 |
· Coding | · 具体编码 | 240 | 650 |
· Code Review | · 代码复审 | 60 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 45 |
Reportin | 报告 | 55 | 110 |
· Test Report | · 测试报告 | 30 | 75 |
· Size Measurement | · 计算工作量 | 15 | 20 |
· Postmortem & Process Improvement Plan | · 事后总结 | 20 | 15 |
合计 | 605 | 1135 |
个人项目WC.exe Node.js+electron实现的更多相关文章
- Vue项目一、node.js和npm的安装和环境搭建
一.为什么安装node.js及npm npm npm是Node.js的包管理工具(package manager),是全球最大的生态系统,同过npm可以找到很多丰富的插件来满足项目的需求. a1.现在 ...
- 个人项目 wc.exe
GitHub地址:https://github.com/oAiuo/wordCount 一.题目描述 Word Count1. 实现一个简单而完整的软件工具(源程序特征统计程序).2. 进行单元测试. ...
- 软工个人项目 ——wc.exe
1.GitHub项目地址 https://github.com/k8kiw/WordCount 2.PSP预计时间 PSP2.1 Personal Software Process Stages 预估 ...
- 记一次使用Node.js electron打包网站的记录
具体步骤请参考:http://blog.csdn.net/a727911438/article/details/70834467 打包时出现了不少问题,逐一记录下来以供其他人参考. package.j ...
- 项目开发---使用node.js中sass语法
前言:本文中所有sass文件都指后缀名为scss的文件.在此也建议使用后缀名为scss的文件,以避免sass后缀名的严格格式要求报错. 一.sass插件的安装: gulp-sass-china // ...
- 个人项目-WC.exe (Java实现)
一.Github项目地址:https://github.com/blanche789/wordCount/tree/master/src/main/java/com/blanche 二.PSP表格 P ...
- 软工个人项目———WC.exe(Java实现)
一.github地址 https://github.com/hhw-15521301615/hello-world 二.PSP表格 PSP2.1 Personal Software Process S ...
- 使用Node.js完成的第一个项目的实践总结
http://blog.csdn.net/yanghua_kobe/article/details/17199417 项目简介 这是一个资产管理项目,主要的目的就是实现对资产的无纸化管理.通过为每个资 ...
- mac下配置Node.js开发环境、express安装、创建项目
mac下配置Node.js开发环境.express安装.创建项目 一.node.js的安装 去官网下载对应的平台版本就可以了,https://nodejs.org 二.express安装 sudo n ...
随机推荐
- html层重叠 相同尺寸透明flash重叠的解决办法
<EMBED style="z-index:1; position:absolute; top:110px;" src="http://www.jintaisd.c ...
- 简单了解InnoDB底层原理
存储引擎 很多文章都是直接开始介绍有哪些存储引擎,并没有去介绍存储引擎本身.那么究竟什么是存储引擎?不知道大家有没有想过,MySQL是如何存储我们丢进去的数据的? 其实存储引擎也很简单,我认为就是一种 ...
- windows异常-环境变量
问题现象: 高级设置:windows 找不到文件 %windir%\systempropertiesadvanced.exe 请确定文件是否正确后,再试一次 基础信息: windows7 专业版 问题 ...
- SSM框架练习之Jsp页面使用taglib标签报错500的问题
最近在练手一个SSM的基于AdminLET框架模板的后台管理系统,使用的环境是tomcat9,使用Maven构建并通过添加Web模板框架的项目,在添加完所有的配置文件后启动tomcat运行,出现了一个 ...
- 牛客练习赛63 牛牛的斐波那契字符串 矩阵乘法 KMP
LINK:牛牛的斐波那契字符串 虽然sb的事实没有改变 但是 也不会改变. 赛时 看了E和F题 都不咋会写 所以弃疗了. 中午又看了一遍F 发现很水 差分了一下就过了. 这是下午和古队长讨论+看题解的 ...
- CF R639 div 2 E Quantifier Question 数学 dfs 图论
LINK:Quantifier Question 题面过长 引起不适 读题花了好长时间 对于 和 存在符合不是很熟练 导致很懵逼的做完了. 好在还算很好想.不过wa到了一个坑点上面 自闭一大晌 还以为 ...
- 4.9 省选模拟赛 圆圈游戏 树形dp set优化建图
由于圆不存在相交的关系 所以包容关系形成了树的形态 其实是一个森林 不过加一个0点 就变成了树. 考虑对于每个圆都求出最近的包容它的点 即他的父亲.然后树形dp即可.暴力建图n^2. const in ...
- Spark中直接操作HDFS
Spark作为一个基于内存的大数据计算框架,可以和hadoop生态的资源调度器和分布式文件存储系统无缝融合.Spark可以直接操作存储在HDFS上面的数据: 通过Hadoop方式操作已经存在的文件目录 ...
- 2080ti的各种问题
1.循环登录 https://blog.csdn.net/miclover_feng/article/details/79201865 2.多版本cuda切换 https://blog.csdn.ne ...
- C++ Json工具--Jsoncpp用法简介
文章目录 Json简介 用法简介 数据类型 C++代码示例 代码执行输出结果 JSON在线解析及格式化验证 - JSON.cn Json简介 JSON(JavaScript Object Notati ...