Java 实现 WC.exe
Github:https://github.com/YJOED/Code/tree/master/WC/src
一、题目:实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。具体功能要求:
- 程序处理用户需求的模式为:wc.exe [parameter] [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 返回更复杂的数据(代码行 / 空行 / 注释行)。(实现)
- 高级功能:
- -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。(未实现)
二、设计思路
利用Java里的IO流对文件内容进行读取,通过创建Scanner类的实例从键盘获取操作命令和目的文件,使用了缓冲流的readline()方法对文件按行读取,使用String类的split()方法、matches()方法对每一行的的字符数、词数、行数进行统计,判断每一行是否是空行、注释行或代码行,使用了IO中的FileFilter()接口以及File类中的listFiles(FileFilter f)方法实现对指定路径下的符合条件的文件进行过滤操作。将基本功能"-l"、“-w”、“-c”、“-a”封装在一个方法里Operation()中,将拓展功能“-a”的实现封装在方法SpecialLine()中,将拓展功能“-s”的实现封装在HandleFile()中,根据输入的命令,调用不同的方法,方法与方法之间也有调用关系。
- 功能模块:
基本功能:Operation(String[] sip) {…}
统计特殊行:SpecialLine(BufferedReader br) {…}
处理多个文件:HandleFile(String[] file) {…}
文件过滤器:class MyFileFilter implements FileFilter{…}
- 流程图:
三、代码分析
- 主方法:获取命令和操作文件的路径、名称,根据输入的命令格式调用相应的方法进行操作:
import java.io.*;
import java.util.*;
import java.lang.String; public class WC {
public static void main(String[] args)throws Exception {
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("please input '[order] [filename]':");
System.out.print("wc.exe ");
String ip[] = input.nextLine().split(" ");
if (ip.length==2) {
Operation(ip);
}else if(ip.length==3 && "-s".equals(ip[0])){
HandleFile(ip);
}else System.out.println("Error");
}
}
2.基本功能——统计字符数、词数、行数,命令与文件以字符串数组的形式作为参数传入该方法,判断输入的命令,执行相应的操作,如果命令为“-a”,调用另一方法统计特殊行:
public static void Operation(String[] sip)throws Exception{
String s;
int linecount = 0, wordcount = 0, charcount = 0;
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(sip[1])));
if ("-l".equals(sip[0])) { // Line count
while ((s = br.readLine()) != null) {
linecount++;
}
System.out.println("Line count:" + linecount);
} else if ("-c".equals(sip[0])) { // Char count
while ((s = br.readLine()) != null) {
charcount = charcount + s.length();
}
System.out.println("Char count:" + charcount);
} else if ("-w".equals(sip[0])) { // Word count
while ((s = br.readLine()) != null) {
String[] sa = s.split("\\s+|\\(|\\)|,|\\.|\\:|\\{|\\}|\\-|\\+|;|\\?|\\/|\\\\|/");
wordcount = wordcount + sa.length;
}
System.out.println("Word count:" + wordcount);
} else if("-a".equals(sip[0])){
SpecialLine(br);
}
br.close();
}
3.统计特殊行:第一次实现时忽略了注释行还可以使用“/*……*/”表示,添加入对应的正则表达式并查找资料后使用了一个标记targer来统计这种情况下的注释行数;
public static void SpecialLine(BufferedReader br)throws Exception {
String s;
String REGEX_1 = "\\s*(\\{|\\})?//.*";
String REGEX_2 = "(\\{|\\})?\\s*";
String REGEX_3 = "\\s*/\\*.*";
String REGEX_4 = ".*\\*/";
boolean targer = false;
int blankline = 0, commentline = 0, codeline = 0;
while ((s = br.readLine()) != null) {
if (s.matches(REGEX_1)) {
commentline++;
}else if (s.matches(REGEX_2)) {
blankline++;
}else if(s.matches(REGEX_3)&&!s.matches(REGEX_4)){
commentline++;
targer = true;
}else if(targer==true){
commentline++;
if(s.matches(REGEX_4)){
targer=false;
}
}else codeline++;
}
System.out.println("Blank Line count:"+blankline);
System.out.println("Comment Line count:"+ commentline);
System.out.println("Code Line count:"+ codeline);
}
4.递归处理目录下符合条件的文件:在该命令中需要对文件进行过滤,只取出那些我们需要操作的文件即可,所以使用了FileFilter接口实现文件的过滤,使用substring()和lastIndexOf()来将模糊输入的文件类型和文件目录分割开。打印文件名并输出统计情况:
public static void HandleFile(String[] file)throws Exception{
String path=null,filetype=null;
String[] sip={file[1],null};
if(file.length>2){
filetype = file[2].substring(file[2].lastIndexOf("."));
path = file[2].substring(0,file[2].lastIndexOf("\\"));
}
File f = new File(path);
MyFileFilter mff = new MyFileFilter(filetype);
File[] files = f.listFiles(mff);
for(int i=0;i<files.length;i++){
sip[1]=files[i].getPath();
System.out.println("File Name: "+files[i].getName());
Operation(sip);
}
}
5.文件过滤器接口的实现,重写了该接口的accept()方法:在accept()方法中,对符合条件的文件返回TRUE,否则返回FALSE:
class MyFileFilter implements FileFilter{
String str;
public MyFileFilter(String _str){
str = _str;
}
public boolean accept(File pathname){
//if(pathname.isDirectory()) return true;
String f = pathname.getName();
if(f.endsWith(str)) return true;
return false;
}
}
四、测试结果
测试用文件:
测试结果:
1.命令“-s”、”-a“:
2.命令“-w”:
3.命令“-c”:
4.命令“-l”:
五、PSP2.1表格
PSP2.1 |
Personal Software Process Stages |
预估耗时(分钟) |
实际耗时(分钟) |
Planning |
计划 |
20 |
20 |
· Estimate |
· 估计这个任务需要多少时间 |
60 |
60 |
Development |
开发 |
180 |
240 |
· Analysis |
· 需求分析 (包括学习新技术) |
20 |
20 |
· Design Spec |
· 生成设计文档 |
30 |
30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
30 |
30 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
10 |
10 |
· Design |
· 具体设计 |
40 |
60 |
· Coding |
· 具体编码 |
180 |
240 |
· Code Review |
· 代码复审 |
25 |
30 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
60 |
60 |
Reporting |
报告 |
30 |
30 |
· Test Report |
· 测试报告 |
20 |
20 |
· Size Measurement |
· 计算工作量 |
20 |
30 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
20 |
25 |
合计 |
745 |
955 |
六、项目小结
通过这一次的程序练习,不仅对软件工程的思想有了更深的认识,在动手实现之前通过估计时间并与实际完成所需时间进行对比,还让我意识到自己其实对实现这样一个小程序还不够熟练,对编程的练习还是太少,需要加强练习,提高技巧,提升能力,以减短不必要的时间的消耗和浪费。
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/ztz1998/wc/tree/master 项目相关要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功 ...
- 软工作业No.1。Java实现WC.exe
网址:https://github.com/a249970271/WC WC 项目要求 wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有w ...
- JAVA实现WC.exe功能
项目要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处理多个文件. 具体功能要求: 程序处理用户需求的模式为: wc.exe [paramet ...
- 软件工程:Java实现WC.exe基本功能
项目相关要求 GitHub地址:https://github.com/3216004716/WC 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功能,并能够快速地处 ...
- 软工作业1—java实现wc.exe
github项目地址 https://github.com/liyizhu/wc.exe WC 项目要求 基本功能列表: wc.exe -c file.c //返回文件 file.c 的字符数 ...
- 软件工程实践一 —— java之wc.exe
SoftwareEngineering-wc github项目地址:https://github.com/CuiLam/SoftwareEngineering-wc 项目相关要求 实现一个统计程序 ...
- 软工作业1:wc.exe项目开发(java)
Github地址:https://github.com/Zzhaomin/learngit 项目相关要求 : wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写一个 ...
- WC.exe(Java实现)
一.GitHub项目地址:https://github.com/nullcjm/mypage 二.项目相关要求: wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数.这个项目要求写 ...
随机推荐
- Flask之视图(一)
2.关于Flask 知识点 从Hello World开始 给路由传递参数 返回状态码 重定向 正则URL 设置cookie和获取cookie 扩展 上下文 请求钩子 Flask装饰器路由的实现 Fla ...
- Rhythmk 一步一步学 JAVA (18) Axis2 创建 WebService
一 > 环境配置 1.下载Axis2: 目前版本为 1.6.2 下载地址: http://axis.apache.org/axis2/java/core/ 下载 axis2-1.6.2-bin. ...
- leetcode537
public class Solution { public string ComplexNumberMultiply(string a, string b) { var aryA = a.Split ...
- jquery中绑定click事件重复执行问题
jquery中单击事件重复多次执行的问题使用如下方式: $('#sub').unbind('click').click(function () { ... });
- Expect 小脚本
简介: Expect 可以替系统管理员完成与系统的交互式操作 shell > yum -y install expect # 可以通过 yum 安装 shell > which expec ...
- requesth获取参数
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) t ...
- 不同应用场景的10个Linux面试问题与解答
本文由 极客范 - 小道空空 翻译自 Avishek Kumar.欢迎加入极客翻译小组,同我们一道翻译与分享.转载请参见文章末尾处的要求. 这一次我们不再介绍某个特定主题的Linux面试问题,而是随机 ...
- Differences Between 3 Types Of Proxy Servers: Normal, Transparent And Reverse Proxy
What is a Proxy Server? A Proxy server is an intermediary machine, between a client and the actual s ...
- 使用RampTexture实现BRDF效果
[使用RampTexture实现BRDF效果] BRDF stands for bidirectional reflectance distribution function. While that ...
- 253. Meeting Rooms II 需要多少间会议室
[抄题]: Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],.. ...