个人项目(wc.exe)
一、项目在GitHub上的地址:
·https://github.com/DawsonHuang/Word_Count
二、项目描述:
·项目名:WordCount(以下简称WC或项目)
·项目简述:实现一个统计程序wc.exe,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他
扩展功能,并能够快速地处理多个文件
·项目具体需求:
·程序处理用户需求的模式为:
·wc.exe [parameter] [file_name] //[file_name]: 文件或目录名,可以处理一般通配符。
·基本功能列表: 【已实现】
·wc.exe -c file.c //返回文件 file.c 的字符数
·wc.exe -w file.c //返回文件 file.c 的词的数目
·wc.exe -l file.c //返回文件 file.c 的行数
·扩展功能: 【已实现】
·-s 递归处理目录下符合条件的文件。
·-a 返回更复杂的数据(代码行 / 空行 / 注释行)。
·注:
·①空行:本行全部是空格或格式控制字符,如果包括代码,则只有不超过一个可显示的字符,
例如“{”。
·②代码行:本行包括多于一个字符的代码。
·③注释行:本行不是代码行,并且本行包括注释。一个有趣的例子是有些程序员会在单字符后面
加注释:} //注释,在这种情况下,这一行属于注释行。
·需求举例:
·wc.exe -s -a *.c //返回当前目录及子目录中所有*.c 文件的代码行、空行、注释行数。
·高级功能: 【已实现】
· -x 参数:这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选
取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
三、设计思路:
·根据输入的需要处理的文件地址,通过IO流来进行文件读取,然后再根据键入的命令类型,调用不同的方法
处理,运用readLine()方法对文件进行按行读取,通过split()方法计算出字符数、单词数、行数;再通过正
则表达式,matches()方法识别统计空行、注释行、代码行;将基本功能封装在BasicOperation方法中,统计
特殊行的功能封装在SpecialLine方法中,递归查找文件的方法为RecrusiveOperation
·编程语言:Java
·功能代码块:
·main()方法:接收输入、调用功能块
·基本功能:BasicOperation(String order,String[] input){....}
·查找特殊行:SpecialLine(String Path){....}
·递归查找文件:RecrusiveOperation(String endwith_name,String[] input,String path){....}
·流程图:
四、代码分析:
·主函数:
1 /**
2 * 本程序支持的命令行格式:
3 * 1、wc.exe -c 文件路径
4 * 2、wc.exe -w 文件路径
5 * 3、wc.exe -l 文件路径
6 * 4、wc.exe -a 文件路径
7 * 5、wc.exe -s -a 文件路径
8 * 6、wc.exe -x 文件路径
9 */
10 public static void main(String[] args) throws Exception{
11 Scanner in = new Scanner(System.in);
12 System.out.println("请注意输入格式 'wc.exe [order] [file_name]:");
13 String[] input = in.nextLine().split(" ");
14 System.out.println(Arrays.toString(input));
15 if("-s".equals(input[1])) { //输入类型是 wc.exe -s ....
16 System.out.println("请输入你要在以上目录中递归查找的文件的后缀:");
17 String endwith_name = in.nextLine(); //后缀名
18 String path; //输入的要递归查询的目录
19 path = input[3]; //文件夹路径
20 RecrusiveOperation(endwith_name,input,path);
21 }else if("-a".equals(input[1])){ //输入类型是 wc.exe -a ....
22 SpecialLine(input[2]);
23 }else{
24 String order = input[1];
25 BasicOperation(order,input);
26 }
27 }
·基本需求:
1 //基本功能实现(-c / -w / -l)
2 public static void BasicOperation(String order,String[] input) throws Exception{
3 int Count_Char=0;
4 int Count_Word=0;
5 int Count_Line=0;
6 FileInputStream file = new FileInputStream(input[2]);
7 InputStreamReader is = new InputStreamReader(file);
8 BufferedReader br = new BufferedReader(is);
9 String s;
10 switch(order) {
11 //计算字符数
12 case "-c":
13 while((s=br.readLine())!=null){
14 Count_Char += s.length();
15 }
16 System.out.println("字符数:"+Count_Char);
17 break;
18 //计算单词数
19 case "-w":
20 while((s=br.readLine())!=null){
21 Count_Word += s.split(" ").length;
22 }
23 System.out.println("单词数:"+Count_Word);
24 break;
25 //计算行数
26 case "-l":
27 while(br.readLine()!=null){
28 Count_Line++;
29 }
30 System.out.println("行数:"+Count_Line);
31 break;
32 default:
33 System.out.println("输入错误!");
34 }
35 }
·递归查找文件
1 //扩展功能实现:-s 递归处理目录下符合条件的文件
2 public static void RecrusiveOperation(String endwith_name,String[] input,String path) throws Exception{
3 List<String> fileNameList = new ArrayList<>();//文件名列表
4 List<String> filePathList = new ArrayList<>();
5 File f = new File(path);
6 if (!f.exists()) { //路径不存在
7 System.out.println("该路径不存在!");
8 }else{
9 if(f.isFile()){ //路径为文件
10 if(f.getName().indexOf(endwith_name)!=-1) {
11 fileNameList.add(f.getName());
12 filePathList.add(f.getAbsolutePath());
13 }
14 }else if(f.isDirectory()){ //路径为文件夹
15 File fa[] = f.listFiles(); //获取改目录下所有文件和目录的绝对路径
16 System.out.println(Arrays.toString(fa));
17 for (int i = 0; i < fa.length; i++) {
18 File fs = fa[i];
19 if(fs.isFile()){
20 if(fs.getName().indexOf(endwith_name)!=-1){
21 fileNameList.add(fs.getName());
22 filePathList.add(fs.getAbsolutePath());
23 }
24 }else if(fs.isDirectory()) {
25 RecrusiveOperation(endwith_name, input, fs.getAbsolutePath());
26 }
27 }
28 }
29 }
30 for(int i = 0;i < filePathList.size();i++){
31 //System.out.println(fileNameList.get(i));
32 System.out.println(filePathList.get(i)+":");
33 switch(input[2]) {
34 case "-c":
35 BasicOperation("-c", input); break;
36 case "-w":
37 BasicOperation("-w", input); break;
38 case "-l":
39 BasicOperation("-l", input); break;
40 case "-a":
41 SpecialLine(filePathList.get(i)); break;
42 }
43 System.out.println();
44 }
45 }
·查找特殊行
1 //扩展功能实现:-a 返回更复杂的数据(代码行/空行/注释行)
2 public static void SpecialLine(String path) throws Exception {
3 int BlankLine = 0; //空行数
4 int AnnotationLine = 0; //注释行数
5 int CodeLine = 0; //代码行数
6 FileInputStream file = new FileInputStream(path);
7 InputStreamReader is = new InputStreamReader(file);
8 BufferedReader br = new BufferedReader(is);
9 String s;
10 //正则表达式表示空行
11 String RegexBlankLine = "(\\{|\\})?\\s*"; //空行
12 //正则表达式表示单行注释
13 String RegexAnnotation = "\\s*(\\{|\\})?\\s*//.*"; //单行注释符‘//’
14 //正则表达式表示多行注释
15 String RegexAnnotationStart = "\\s*(\\{||\\})?/\\*.*"; //多行注释起始符‘/*’
16 String RegexAnnotationEnd = ".*\\*/"; //多行注释结束符‘*/’
17 while ((s = br.readLine()) != null) {
18 if (s.matches(RegexBlankLine)) {
19 BlankLine++;
20 } else if (s.matches(RegexAnnotation)) {
21 AnnotationLine++;
22 } else if (s.matches(RegexAnnotationStart)) {
23 do {
24 AnnotationLine++;
25 s = br.readLine();
26 } while (!s.matches(RegexAnnotationEnd));
27 AnnotationLine++; //多行注释结束符所在行也应加上
28 } else {
29 CodeLine++;
30 }
31 }
32 System.out.println("空白行:" + BlankLine + " 行.");
33 System.out.println("注释行:" + AnnotationLine + " 行.");
34 System.out.println("代码行:" + CodeLine + " 行.");
35 }
public static void _x(){
new FileFrame();
}
·-x
1 package JFrame;
2
3 import com.HDH.WC;
4
5 import java.awt.*;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.io.File;
9 import javax.swing.*;
10
11 /**
12 * GUI
13 * @author Dawson_Huang
14 * @Date 2020/3/14 - 9:27
15 */
16
17 public class FileFrame implements ActionListener {
18 JFrame frame = new JFrame("文件选择");// 框架布局
19 JTabbedPane tabPane = new JTabbedPane();// 选项卡布局
20 Container con = new Container();
21 JLabel label1 = new JLabel("文件目录");
22 JTextField text1 = new JTextField();// TextField 目录的路径
23 JButton button1 = new JButton("选择");// 选择
24 JFileChooser jfc = new JFileChooser();// 文件选择器
25 JLabel label2 = new JLabel("选择命令");
26 JCheckBox jCheckBoxC = new JCheckBox("-c");
27 JCheckBox jCheckBoxW = new JCheckBox("-w");
28 JCheckBox jCheckBoxL = new JCheckBox("-l");
29 JCheckBox jCheckBoxA = new JCheckBox("-a");
30 JButton button2 = new JButton("确定");//
31
32 public static void main(String[] args) {
33 new FileFrame();
34 }
35
36 public FileFrame() {
37 jfc.setCurrentDirectory(new File("d://")); // 文件选择器的初始目录为d盘
38 double lx = Toolkit.getDefaultToolkit().getScreenSize().getWidth(); // 显示屏幕的宽度
39 double ly = Toolkit.getDefaultToolkit().getScreenSize().getHeight(); // 显示屏幕的高度
40 frame.setLocation(new Point((int) (lx / 2) - 150, (int) (ly / 2) - 150)); // 窗口出现的位置
41 frame.setSize(500, 360);// 设定窗口大小
42 frame.setContentPane(tabPane);// 设置布局
43 label1.setBounds(10, 10, 70, 20);
44 text1.setBounds(75, 10, 120, 20);
45 button1.setBounds(210, 10, 50, 20);
46 label2.setBounds(10, 60, 70, 20);
47 button2.setBounds(240, 60, 60, 20);
48 jCheckBoxC.setBounds(80, 60, 40, 20);
49 jCheckBoxW.setBounds(120, 60, 40, 20);
50 jCheckBoxL.setBounds(140, 60, 40, 20);
51 jCheckBoxA.setBounds(180, 60, 40, 20);
52 button1.addActionListener(this); // 添加事件处理
53 button2.addActionListener(this); // 添加事件处理
54 con.add(label1);
55 con.add(text1);
56 con.add(button1);
57 con.add(label2);
58 con.add(jCheckBoxC);
59 con.add(jCheckBoxW);
60 con.add(jCheckBoxL);
61 con.add(jCheckBoxA);
62 con.add(button2);
63 frame.setVisible(true);// 窗口可见
64 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 使能关闭窗口,结束程序
65 tabPane.add("1面板", con);// 添加布局1
66 }
67
68 public String path;
69 public String order;
70 /**
71 * 时间监听的方法
72 */
73 public void actionPerformed(ActionEvent e) {
74 if (e.getSource().equals(button1)) { // 判断触发方法的按钮是哪个
75 int state = jfc.showOpenDialog(null);// 此句是打开文件选择器界面的触发语句
76 if (state == 1) {
77 return;
78 } else {
79 File f = jfc.getSelectedFile();// f为选择到的目录
80 text1.setText(f.getAbsolutePath());
81 path = f.getAbsolutePath();
82 }
83 }
84 if (e.getSource().equals(button2)) {
85 JCheckBox[] jcbs = {jCheckBoxA, jCheckBoxC, jCheckBoxL, jCheckBoxW};
86 for (JCheckBox j : jcbs) {
87 if (j.isSelected()) {
88 order = j.getText();
89 switch(order) {
90 case "-c":
91 try {
92 WC.BasicOperation("-c",path);
93 } catch (Exception ex) {
94 ex.printStackTrace();
95 }
96 break;
97 case "-w":
98 try {
99 WC.BasicOperation("-c",path);
100 } catch (Exception ex) {
101 ex.printStackTrace();
102 }
103 break;
104 case "-l":
105 try {
106 WC.BasicOperation("-c",path);
107 } catch (Exception ex) {
108 ex.printStackTrace();
109 }
110 break;
111 case "-a":
112 try {
113 WC.SpecialLine(path);
114 } catch (Exception ex) {
115 ex.printStackTrace();
116 }
117 break;
118 }
119 }
120 }
121 }
122 }
123 }
五、测试运行:
·文件目录:
·测试结果:
·命令"-c":
·命令"-w":
·命令"-l":
·命令"-s -a":
·命令"-x":
六、PSP2.1表格:
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
25 |
20 |
· Estimate |
· 估计这个任务需要多少时间 |
60 |
60 |
Development |
开发 |
180 |
240 |
· Analysis |
· 需求分析 (包括学习新技术) |
20 |
20 |
· Design Spec |
· 生成设计文档 |
30 |
30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 |
20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
· Design |
· 具体设计 |
60 |
60 |
· Coding |
· 具体编码 |
240 |
360 |
· Code Review |
· 代码复审 |
25 |
30 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
40 |
60 |
Reporting |
报告 |
35 |
40 |
· Test Report |
· 测试报告 |
20 |
20 |
· Size Measurement |
· 计算工作量 |
15 |
25 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
20 |
30 |
合计 |
800 |
1025 |
七、遇到的困难及解决方法:
不知如何表示空行、注释行、代码行,通过百度、CSDN学习了正则表达式,问题已解决。
八、项目小结:
通过这次练习,我对软件工程有了进一步的了解,通过PSP表格前后对比,发现我还需要学习的知识点还很多,缺乏项目经验。
个人项目(wc.exe)的更多相关文章
- 个人项目 wc.exe
GitHub地址:https://github.com/oAiuo/wordCount 一.题目描述 Word Count1. 实现一个简单而完整的软件工具(源程序特征统计程序).2. 进行单元测试. ...
- 个人项目WC.exe Node.js+electron实现
前言 实现语言:Javascript 编译工具:webstorm GitHub:https://github.com/NPjuan/WC.git 项目要求 wc.exe 是一个常见的工具,它能统计文本 ...
- 软工个人项目 ——wc.exe
1.GitHub项目地址 https://github.com/k8kiw/WordCount 2.PSP预计时间 PSP2.1 Personal Software Process Stages 预估 ...
- 个人项目-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 ...
- 软工作业1:wc.exe项目开发(java)
Github地址:https://github.com/Zzhaomin/learngit 项目相关要求 : wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个 ...
- 个人项目(WC.exe)(java)(基于图形界面)
一.Github项目地址:https://github.com/Leungdc/ENhomework 二.PSP: PSP2.1 Personal Software Process Stages 预估 ...
- 个人项目作业(wc.exe)
1.GitHub项目地址 https://github.com/QiuBin666/WC 项目介绍: 题目描述 Word Count1. 实现一个简单而完整的软件工具(源程序特征统计程序).2. 进行 ...
- 个人项目作业——wc.exe
一.Github项目地址 https://github.com/PIPIYing/wc 二.项目概况 项目描述 Word Count 1. 实现一个简单而完整的软件工具(源程序特征统计程序). 2. ...
随机推荐
- S5830 android 2.3.4和2.3.7
12年元旦买的手机S5830,原机自带2.3.4的系统. 看到人家的机子2.3.6的效果稍微绚一点,动了想刷机的念头. 前两天刷了2.3.7,效果还满意,用的还舒服,感觉就是有些费电, 本来就对智能手 ...
- Javascript的运行效率是原生代码的20%-30%
所以jser们,写代码更仔细些吧. http://www.cnblogs.com/codemood/p/3213459.html
- 【JVM】肝了一周,吐血整理出这份超硬核的JVM笔记(升级版)!!
写在前面 最近,一直有小伙伴让我整理下关于JVM的知识,经过十几天的收集与整理,初版算是整理出来了.希望对大家有所帮助. JDK 是什么? JDK 是用于支持 Java 程序开发的最小环境. Java ...
- 《.NET 5.0 背锅案》第7集-大结局:捉拿真凶 StackExchange.Redis.Extensions 归案
第1集:验证 .NET 5.0 正式版 docker 镜像问题 第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore 第3集-剧情反转:EnyimMemcachedCo ...
- 玩转 Comparator 和 Comparable 两接口
最近项目中有排序的需求,就查看了一下Java文档,发现有两个接口都可以进行排序,Comparable 和 Comparator 两接口到底有啥区别?何时用?怎么用?使用场景我都在底下一一研究分享出来: ...
- sublime 3 phpfmt配置(大括号对齐)
默认选项: default: phpfmt.sublime-settings: { "version": 2, "php ...
- kali 系列学习04 - 漏洞扫描
一.比较三类漏洞扫描工具 1.Rapid7 Nexpose 适合较大网络 2.Nessus 更经济,可以申请个人版,搞之后硬盘占用达到20G 以上2个是商业软件,使用容易上手,输入IP地址就能完成所有 ...
- php(tp5) 生成二维码
phpqrcode类库官网下载地址:https://sourceforge.net/projects/phpqrcode/ 1.我们先看看php是怎么生成二维码的 1.首先我们先下载一下 phpqr ...
- 企业级工作流解决方案(八)--微服务Tcp消息传输模型之服务端处理
服务端启动 服务端启动主要做几件事情,1. 从配置文件读取服务配置(主要是服务监听端口和编解码配置),2. 注册编解码器工厂,3. 启动dotnetty监听端口,4. 读取配置文件,解析全局消息处理模 ...
- selenium+python自动化元素定位
最近学习自动化测试,终于初步学习完成,需要进行博客日志总结,加深巩固自己的知识. 元素的八种定位方式 1.id 以百度为例子 我们在python输入的元素定位语法:bs.find_element_by ...