个人项目:实现wc.exe(Java)
2021-06-29 23:07
标签:splay sof direction com process 代码覆盖率 on() [] fileread 本项目Github地址:https://github.com/NNewBoy/wc 基本功能:(已实现) -c 统计文件字符数 -w 统计文件词的数目 -l 统计文件行数 扩展功能:(已实现) -s 递归处理目录下符合条件的文件 -a 返回更复杂的数据(代码行 / 空行 / 注释行) 高级功能:(未实现) -x 显示图形界面 拿到项目后,首先理清项目需求,然后规划项目框架,根据框架设计功能函数,思考函数的实现方法,查找资料,本次项目查找了关于正则表达式的资料;设计部分完毕,开始代码编写,最后就是检测代码,修改代码。 代码分成两大部分,5个类。 第一命令部分:Main类实现输入命令,Command类实现对命令的解析 输入命令后调用Command类解析命令,Command解析命令后调用功能类。 第二功能部分:Basicfunction类实现基本功能,Directory类实现-s功能,Increasedfunction类实现-a功能 基本功能通过正则表达式匹配每个字符实现;-s由于要递归目录里的多个文件,跟其他命令实现过程有所区别,因此分开编写,通过File类的listFiles()方法取得目录里符合条件的文件,然后各自调用Command类;-a也是使用正则表达式,统计代码行、空行、注释行,然后返回数目。 对输入的命令,先判断是否有-s命令,是则调用Direction类遍历出符合条件的文件路径,否则当前路径就是目标文件的路径。 遍历出符合条件的文件路径,对每个符合条件的文件调用Command类。 通过read()函数统计字符数、词数、行数,然后再返回。 通过read()函数统计空行数、代码行数、注释行数;多行注释开始时explainValue=true,结束时为false,以此来判断注释行。 空文件: 只有一个字符的文件:
代码覆盖率: PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 30 15 · Estimate · 估计这个任务需要多少时间 30 15 Development 开发 680 1213 · Analysis · 需求分析 (包括学习新技术) 120 157 · Design Spec · 生成设计文档 30 75 · Design Review · 设计复审 (和同事审核设计文档) 30 60 · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 25 · Design · 具体设计 80 105 · Coding · 具体编码 300 566 · Code Review · 代码复审 60 105 · Test · 测试(自我测试,修改代码,提交修改) 30 120 Reporting 报告 150 145 · Test Report · 测试报告 60 60 · Size Measurement · 计算工作量 30 25 · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 60 合计 860 1373 从PSP表格可以看出,我在学习新技术和具体编码上花的时间最多,这是因为我对java这门语言掌握的不是很到位,有很多常用库函数的用法都没记住,平时做项目练习太少,此后应多加训练敲代码的能力。此次项目运用JUnit的进行单元测试,很方便地得出了代码的一些bug,这比以前的检查bug的方法都要快捷很多,不过本次项目没有采用“测试驱动开发”(TDD)进行,下次项目尝试TDD,以使项目更加便捷地完成。本次项目最大的收获就是学会用科学的开发模式进行开发,了解到需求分析、设计与测试对一个项目的重要性。 个人项目:实现wc.exe(Java) 标签:splay sof direction com process 代码覆盖率 on() [] fileread 原文地址:https://www.cnblogs.com/cappuccinoboy/p/9644074.html项目相关要求
解题思路
设计实现过程
代码说明
命令解析:
public class Command {
void command(String input,String filename,Matcher matcher) {
try {
Boolean s = false;
List
实现-s命令:
public class Directory {
void readDirectory(String filename , String input) {
Pattern pattern = Pattern.compile("\\-[cwla]");
Matcher matcher = pattern.matcher(input);
File filedirectory = new File(filename);
File[] files = filedirectory.listFiles();
for (File file : files) {
//遍历路径里的文件夹
if (file.isDirectory()) {
readDirectory(file.getPath(),input);
} else {
//实现-c -w -l -a 命令
new Command().command(input,file.getPath(),matcher);
}
}
}
}
实现-c -w -l 命令:
public class Basicfunction {
private String s1;
private String s2;
private int ccount;
private int wcount;
private int lcount;
private void read(String filename) throws IOException {
BufferedReader brin = new BufferedReader(new FileReader(filename));
while ((s1=brin.readLine())!=null) {
ccount += s1.length();//统计字符数
s1 = s1 + " ";
s2 += s1;
lcount ++;//统计行数
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher(s1);
while (matcher.find()) {
wcount++;//统计词数
}
}
brin.close();
}
public void c(String filename) {
try {
read(filename);
System.out.println("字符数:"+ccount);
} catch (Exception e) {
System.out.println("输入路径出错");
}
}
public void w(String filename) {
try {
read(filename);
System.out.println("词的数目:"+wcount);
} catch (Exception e) {
System.out.println("输入路径出错");
}
}
public void l(String filename) {
try {
read(filename);
System.out.println("行数:"+lcount);
} catch (Exception e) {
System.out.println("输入路径出错");
}
}
}
实现-a命令:
public class Increasedfunction {
private int emptyLine = 0,codeLine = 0,explainLine = 0,lineCount = 0;
//通过正则表达式匹配指定字符
private int match(String regex , String sentence) {
int i = 0;
Pattern pattern1 = Pattern.compile(regex);
Matcher matcher1 = pattern1.matcher(sentence);
while (matcher1.find()) {
i++;
}
return i;
}
private void read(String filename) throws IOException {
//空字符数
int emptyCount;
//各种标点符号数
int emptyCharCount;
//词数
int displayCharCount;
//单行注释符"//"
int explainCount1;
//多行注释开始"/*"
int explainCount2;
//多行注释结束"*/"
int explainCount3;
//含有注释符"/*"的代码行
int explainCount4;
//含有注释符"//"的代码行
int explainCount5;
String s1;
Boolean explainValue = false;
BufferedReader brin = new BufferedReader(new FileReader(filename));
while ((s1=brin.readLine())!=null) {
emptyCount = match("\\s",s1);
emptyCharCount = match("\\S\\W",s1);
displayCharCount = match("\\w",s1);
explainCount1 = match("\\/\\/",s1);
explainCount2 = match("\\/\\*",s1);
explainCount3 = match("\\*\\/",s1);
explainCount4 = match("\\S{2,}.*\\/\\*",s1);
explainCount5 = match("\\S{2,}.*\\/\\/",s1);
if (explainCount2 != 0) {
//多行注释开始,判断是注释行还是代码行
explainValue = true;
if (explainCount4 != 0) {
explainLine--;
codeLine++;
}
} else if (explainCount3 != 0) {
//多行注释结束
explainValue = false;
explainLine++;
} else if (explainCount1 != 0) {
//含单行注释,判断是注释行还是代码行
if (explainCount5 != 0) {
codeLine++;
} else {
explainLine++;
}
} else if (!explainValue && displayCharCount == 0 && (emptyCount != 0 || emptyCharCount )) {
//空行情况
emptyLine++;
} else if (!explainValue) {
//剩下的是代码行
codeLine++;
}
if (explainValue) {
//多行注释,超过两行的情况
explainLine++;
}
if (explainCount2 != 0 && explainCount3 != 0) {
//多行注释只有一行的情况
explainLine--;
}
}
brin.close();
}
public void a(String filename) {
try {
read(filename);
System.out.println("空行数:"+emptyLine);
System.out.println("代码行数:"+codeLine);
System.out.println("注释行数:"+explainLine);
} catch (Exception e) {
System.out.println("输入路径出错");
}
}
}
测试运行
只有一个词的文件:
只有一行的文件:
一个典型的源文件:PSP
项目小结
上一篇:第一章 Java多线程技能