软件工程实践一 —— java之wc.exe
SoftwareEngineering-wc
github项目地址:https://github.com/CuiLam/SoftwareEngineering-wc
项目相关要求
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能
-c 返回文件字符数
-w 返回词的数目
-l 返回行数
扩展功能
-s 递归处理目录下符合条件的文件
-a 返回更复杂的数据(代码行 / 空行 / 注释行)
高级功能
-x 命令行输入-x参数,程序显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
PSP
| PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
|---|---|---|---|
| Planning | 计划 | ||
| · Estimate | · 估计这个任务需要多少时间 | 30 | 20 |
| Development | 开发 | ||
| · Analysis | · 需求分析 (包括学习新技术) | 180 | 90 |
| · Design Spec | · 生成设计文档 | 180 | 30 |
| · Design Review | · 设计复审 (和同事审核设计文档) | 60 | 30 |
| · Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 15 |
| · Design | · 具体设计 | 30 | 10 |
| · Coding | · 具体编码 | 300 | 360 |
| · Code Review | · 代码复审 | 30 | 15 |
| · Test | · 测试(自我测试,修改代码,提交修改) | 60 | 90 |
| Reporting | 报告 | ||
| · Test Report | · 测试报告 | 300 | 180 |
| · Size Measurement | · 计算工作量 | 10 | 10 |
| · Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 10 |
| 合计 | 1210 | 860 |
解题思路
项目要求分三级,具体、扩展和高级。
具体功能及整个项目的核心基础功能,因此应该从具体功能入手。完成了单文件之后再去进行多文件和图形化界面选择文件将会简单很多。
通览项目要求,是对文件/文件夹进行统计,可以说是一个简单的文件/文件夹的工具类。
-c 文件字符数
在这里我将文件字符数归结为文件中可见的字符数量,即\n\r\t等并未列入计算。
基于这样的定义和考虑,打算从IO流中读取文件每行并采用String.length()方法计算文件字符数。
-w 词的数目
关于词的数目在这里定义为单个英文字母/连续的英文字母或纯数字组合或英文字母和数字的组合。
因此在项目中设计使用正则来进行统计。
-l 行数
在行数方面的设计并没有做多想,仅仅通过读取IO流行数统计文件行数
-a 代码行 / 空行 / 注释行
在这一个参数上的考虑是从容易统计的进行。
空行
全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,例如“{”
判断空行分三步
使用
String.trim();去除行中首尾空白判断去除首尾空白之后长度
使用
String.length()计算剩余长度若长度等于0则视为空行
如果等于1,则判断这个剩余这一个长度的字符串是不是非单词字符
若是,则该行为空行
否则,部位空行
如果长度大于1,则视为非空行
注释行
// /** */``}\\在项目中被定义为注释行
在这里计划使用正则表达式进行匹配统计
代码行
除开空行和注释行其余的被视为代码行
设计实现过程
项目设计有两个类,如下图所示


在main()中使用循环解析参数,参数字符串以-开头的视为参数,其余视为路径
根据路径再分文件和文件夹的处理
如果是文件夹则进行递归文件处理
代码说明
main()参数的处理List<String> params = new ArrayList<>();
for (String s : args) {
if (s.equals("-x")) {
main.showGui();
} else if(s.startsWith("-")) {
params.add(s);
} else if (isFile(s)) {
System.out.println(s);
for (String param : params)
main.operSingleFile(s, param);
} else if (isDirectory(s)) {
main.operFiles(s, params, null);
} else {
//s可能是通配符
String currentPath = main.getCurrentPath();
main.operFiles(currentPath, params, getRegex(s));
return;
}
}文件行数统计
while (bufferedReader.readLine() != null)
line++;单行统计单词个数
String s = string.trim(); //首先去除字符串收尾缩进
String regex = "[a-zA-Z0-9]+\\b";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
count++;
}统计字符数
while ((line = bufferedReader.readLine()) != null)
count += line.length();判断是否是注释行
String regex = "^\\W*$";
//如果包含这些表示可能是注释行
//包含并且注释符号前全为非字符的一定是注释行
if (line.contains("//")) {
return line.split("//").length == 0 || Pattern.matches(regex, line.split("//")[0]);
} else if (line.contains("/**")) {
return Pattern.matches(regex, line.split("//*/*")[0]);
} else if (line.contains("*/")) {
return Pattern.matches(regex, line.split("/*/")[0]);
} else if (line.contains("<!--")) {
return Pattern.matches(regex, line.split("//")[0]);
} else if (line.contains("--!>")) {
return Pattern.matches(regex, line.split("//")[0]);
} else if (line.contains("*")) {
return Pattern.matches(regex, line.split("//*")[0]);
}
测试运行
运行参数
-l -w -c /home/lam/gdut/SoftwareEngineering/DemoOne/src/com/lam/MainIndex.java输出情况
/home/lam/gdut/SoftwareEngineering/DemoOne/src/com/lam/MainIndex.java
行数:155
单词个数:452
字符数:5031运行参数
-l -w -c -a/home/lam/gdut/SoftwareEngineering/DemoOne/src/com/lam输出
/home/lam/gdut/SoftwareEngineering/DemoOne/src/com/lam/util/FileUtil.java
行数:247
单词个数:582
字符数:7226
空行:39
代码行:153
注释行:55
/home/lam/gdut/SoftwareEngineering/DemoOne/src/com/lam/MainIndex.java
行数:155
单词个数:452
字符数:5031
空行:32
代码行:121
注释行:2运行参数
-x

单元测试


代码覆盖率如下图所示


项目小结
这是我第一次在实践项目中使用软件工程的思想。对于一开始PSP表格的时间预计,有些拿捏不准。对于自己每项任务完成时间的估计没有考量。但是总归来说在项目开始还是有自己的项目阶段步骤的考虑。
整个项目实践下来还不够成熟和完善。
在一些需求的考虑上考量不足,单元测试之后仍有改动。
希望这一次的练习能为接下来的项目打下基础。
软件工程实践一 —— java之wc.exe的更多相关文章
- 小白のjava实现wc.exe功能
GitHub地址 项目完成情况 基本功能列表(已实现) wc.exe -c file.c //返回文件 file.c 的字符数 wc.exe -w file.c //返回文件 file. ...
- 软件工程:Java实现WC.exe基本功能
项目相关要求 GitHub地址:https://github.com/3216004716/WC 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处 ...
- Java 实现 WC.exe
Github:https://github.com/YJOED/Code/tree/master/WC/src 一.题目:实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他 ...
- 软工作业1—java实现wc.exe
github项目地址 https://github.com/liyizhu/wc.exe WC 项目要求 基本功能列表: wc.exe -c file.c //返回文件 file.c 的字符数 ...
- java实现wc.exe
Github地址:https://github.com/ztz1998/wc/tree/master 项目相关要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功 ...
- 软工作业No.1。Java实现WC.exe
网址:https://github.com/a249970271/WC WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有w ...
- JAVA实现WC.exe功能
项目要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处理多个文件. 具体功能要求: 程序处理用户需求的模式为: wc.exe [paramet ...
- 软件工程 wc.exe 代码统计作业
软件工程 wc.exe 代码统计作业分享 1. Github 项目地址 https://github.com/EdwardLiu-Aurora/WordCount 更好地阅读本文,可点击这里 基本要求 ...
- 软工作业1:wc.exe项目开发(java)
Github地址:https://github.com/Zzhaomin/learngit 项目相关要求 : wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个 ...
随机推荐
- mysql实战优化之三:表优化
对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈.所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问. 如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理 ...
- 分表分库之二:唯一ID的生成方法
一.为什么要全局唯一? 我们在对数据库集群作扩容时,为了保证负载的平衡,需要在不同的Shard之间进行数据的移动, 如果主键不唯一,我们就没办法这样随意的移动数据.起初,我们考虑采用组合主键来解决这个 ...
- idea完成分支和主干的合并
我们在开发一个项目的时候,我们可能会创建一个分支和一个主干.对于分支而言,我们一般在开发的时候可能会使用,但是在项目上线的时候,我们抽取的项目的地址可能是主干的svn地址,这时我们需要将分支上的svn ...
- Linux内核中常见内存分配函数
1. 原理说明 Linux内核中采用了一种同时适用于32位和64位系统的内存分页模型,对于32位系统来说,两级页表足够用了,而在x86_64系统中,用到了四级页表,如图2-1所示.四级页表分 ...
- c# 各种tips
1.lock 类似于 java中的synchronized,对对象或代码块加上互斥锁. 2.c#中的lambda表达式, ForEach(x => f(n)) 3.c# 中的 something ...
- PHP函数(二)-不定参数的传递
如果要传递不定数量的参数,需要使用func_get_args()函数来传递 func_num_args()函数用来返回参数的总数 <?php function more_args(){ $arg ...
- Flask之数据库操作
4.2 数据库基本操作 在Flask-SQLAlchemy中,插入.修改.删除操作,均由数据库会话管理.会话用db.session表示.在准备把数据写入数据库前,要先将数据添加到会话中然后调用comm ...
- 前端学习---html基础知识
HTML基本知识 学习html首先我们先看看HTML本质: web框架本质 我们在学socket,我们创建一个socketserver,然后运行起来,有一个client客户端要连接socket服务端, ...
- Protege4.3使用入门(二)
1.支持OWLViz 利用OWLViz查看我们构建Class的结构图.如果尚未安装,请到http://www.graphviz.org/pub/graphviz/stable/windows/grap ...
- c++builder delphi 调用dll dll编写
c++builder动态调用dll // 定义 typedef int __stdcall MyFunction (int x, char *str); ; String dllName = &quo ...