github项目地址
预测PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 60 | |
· Estimate | · 估计这个任务需要多少时间 | 30 | |
Development | 开发 | 600 | |
· Analysis | · 需求分析 (包括学习新技术) | 100 | |
· Design Spec | · 生成设计文档 | 60 | |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | |
· Design | · 具体设计 | 200 | |
· Coding | · 具体编码 | 200 | |
· Code Review | · 代码复审 | 100 | |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | |
Reporting | 报告 | 100 | |
· Test Report | · 测试报告 | 30 | |
· Size Measurement | · 计算工作量 | 30 | |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 100 | |
合计 |
项目要求及解题思路
实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
基本功能
wc.exe -c file.c //返回文件 file.c 的字符数
- 具体思路:使用io流读取目标文件的每一行,并累计每一行字符串的长度。
wc.exe -w file.c //返回文件 file.c 的词的数目
- 具体思路:使用正则表达式确定所读取的每行字符串中所匹配到的单词数,进行累加。
wc.exe -l file.c //返回文件 file.c 的行数
- 具体思路:直接累计读取的行数。
拓展功能
-s 递归处理目录下符合条件的文件。
- 具体思路:
- 文件格式有要求,所以先写了一个文件名过滤器
- 判断传入参数是否为需求文件或者目录
- 递归查找,若为目标文件,输出文件名。若为目录,则递归查找。
-a 返回更复杂的数据(代码行 / 空行 / 注释行)。
- 对需求的定义:
-
空行:整行为空白字符,或者空白字符加[{;}]
-
注释行:
单行注释:[{;}]?//开头的视为注释行
块注释:[{;}]?/开头,/(//s)+结尾的视为快注释中的行。 3. 代码行:文本总行数去掉空行和注释行。
-
高级功能:
-x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
遇到的困难及解决方法
困难描述
在匹配注释行数中,对正则表达式不过熟悉,并且对于注释行可能出现的类型没有全面认识。
做过哪些尝试
放弃使用正则表达式,转而使用条件判断语句判断每一行数据。单行注释比较简单。多行注释要注意判断每行读取到是否含有/*,并且做标记,直到读到*/。
是否解决
是的。不过最后还是使用正则表达式,因为代码比较简洁。
有何收获
熟悉了正则表达式的某些应用
设计实现过程
说明:使用两个类处理程序,一个Worker类用于实现特定需求,一个是Main类用于根据所输入参数调用相应方法实现需求。
代码说明
- 单词数:
单词定义:只包含连续的英文字母,在这里没有考虑单词跨行的情况
1 String REGEX ="\\b[a-zA-Z]+\\b"; 2 String currentLine; 3 Pattern p = Pattern.compile(REGEX); 4 Matcher m; 5 while((currentLine=reader.readLine())!=null) { 6 currentLine=currentLine.trim(); 7 m= p.matcher(currentLine); 8 while(m.find()) { 9 count++;10 }11 }
- 字符数:
字符定义:包括空白字符
1 while((currentLine=reader.readLine())!=null) {2 count+=currentLine.length();3 }
- 注释行数
注释行的定义上文已提及,在这里不再赘述。
1 /* 2 注释说明: 3 单行注释:[{;}]?//开头的视为注释行 4 块注释:[{;}]?/*开头,*/(//s)+结尾的视为快注释中的行。 5 由此写出对应的正则表达式进行匹配。 6 */ 7 String Single_Line_Note_REGEX="(\\s*)([{};]?)(\\s*)(//)(.*)"; 8 String Block_Note_Start_REGEX="(\\s*)([{};]?)(\\s*)(/{1})(\\*{1})(.*)"; 9 String Block_Note_End_REGEX="(.*)(\\*{1})(/{1})(\\s*)";10 while((currentLine=reader.readLine())!=null) {11 if(currentLine.matches(Single_Line_Note_REGEX)) {12 count++;13 }else if(currentLine.matches(Block_Note_Start_REGEX)) {14 count++;15 while((currentLine=reader.readLine())!=null) {16 if(currentLine.matches(Block_Note_End_REGEX)) {17 count++;18 break;19 }else {20 count++;21 }22 }23 }24 }
- 查询指定文件
根据输入参数指定文件和过滤类型
1 /* 2 思路分析:递归判断输入参数是否为目录,若是递归查询,若为目标文件,则输出文件名。 3 4 */ 5 public class myFileFilter implements FileFilter { 6 @Override 7 public boolean accept(File file) { 8 9 if(file.isDirectory()) 10 return true; 11 else{ 12 String name = file.getName(); 13 if(name.endsWith(getFile_type())){14 return true; 15 } 16 else {17 return false; 18 } 19 } 20 21 } 22 23 } 24 public void getAllFilePath(String rootPath) { 25 26 File file = new File(rootPath); 27 File[] files = file.listFiles(new myFileFilter()); 28 for(int i=0;i
测试运行
基本功能的测试
高级功能测试
获取特殊行数
获取指定文件名
实际PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
Planning | 计划 | 60 | 30 |
· Estimate | · 估计这个任务需要多少时间 | 30 | 30 |
Development | 开发 | 600 | 600 |
· Analysis | · 需求分析 (包括学习新技术) | 100 | 100 |
· Design Spec | · 生成设计文档 | 60 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 60 | 60 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | |
· Design | · 具体设计 | 200 | 200 |
· Coding | · 具体编码 | 200 | 180 |
· Code Review | · 代码复审 | 100 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 30 | 30 |
Reporting | 报告0 | 100 | 160 |
· Test Report | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 30 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 100 | 80 |
合计 | 760 | 790 |
项目小结
不足之处
- 代码不够简洁,数据没有封装好:在观察了其他同学提交的作业,我深深感到自己编写的代码规范性不好,没有对所有代码的封装保持一致的风格。数据封装这方面没有把相关常量定义在一个接口文件中。
学习收获
- 正则表达式:对正则表达式重新了解并做了笔记
- javaAPI中的一些方法:文件名过滤器,分割字符串,去除字符串空白字符。