2018年系统分析与设计—个人项目作业

题目来自于 :https://edu.cnblogs.com/campus/xnsy/2018Systemanalysisanddesign/homework/2120

本次作业Gitee项目地址 :https://gitee.com/moxxxmo/WordCount

一、项目简介


1. 本项目的需求:

通过程序设计,编写一个可执行文件exe能够对源程序文件进行统计字符数、单词数、行数,统计结果可以以指定的格式输出到默认文件中。

2.参数及其约定如下:

基本功能:

扩展功能:

wc.exe -s                        //递归处理目录下符合条件的文件

wc.exe -a file.c              //返回代码行 / 空行 /  注释行

wc.exe -e stopList.txt    //停用词表,统计文件单词总数时,不统计该表中的单词

高级功能:

wc.exe -x //该参数单独使用,如果存在参数,则显示图形界面,用户通过这个界面选取单个文件,程序就会显示文件的字符数、单词数、行数等。

二、完成作业过程:


1. 编写PSP

PSP要在项目开始之前和项目结束时进行编写,要根据自己的能力和任务量编写。

PSP2.1

PSP阶段

预估耗时(分钟)

实际耗时(分钟)

Planning 计划 60 40
· Estimate · 估计这个任务需要多少时间 60 40
Development 开发  450  700
· Analysis · 需求分析 (包括学习新技术)  90  120
· Design Spec · 生成设计文档  40 30
· Design Review · 设计复审 (和同事审核设计文档)  20  15
· Coding Standard · 代码规范 (为目前的开发制定合适的规范)  20 10
· Design · 具体设计  60  60
· Coding · 具体编码  130  350
· Code Review · 代码复审  30  25
· Test · 测试(自我测试,修改代码,提交修改)  60  90
Reporting 报告  45  80
· Test Report · 测试报告 30  65
· Size Measurement · 计算工作量  10  10
· Postmortem & Process Improvement Plan .事后总结并提出改进计划  5  5
  合计  555  820

分析与总结:我的前后时间出现差别我觉得存在的原因在于我不能正确的预估我学习一个新知识和如何将这个知识快速地运用进编码的时间,所以主要的时间差别在需求分析和编码上。

2. 解题思路

在我拿到这个项目之后,我先对题目的要求进行了分析。然后决定了要使用java语言来实现,此项目中需要运用到java中对文件的操作,因为我没有学习过这部分的内容,所以我知道我的第一步要做的就是先学习java文件操作的知识。第二步就是分析整个项目如何进行设计,从类方面划分的话,我认为可以分为两个类,一个是主函数类(MainCount),一个是功能函数类(WordCount)。然后在功能函数类中将基本功能中要求的四个命令实现,以四个函数的方式进行实现,分别为统计字符数函数、统计行数函数、统计单词数函数、文件输出函数。第三步、思考如何进行单元测试,单元测试的设计可以在写具体功能代码实现之前,也可以在写完具体功能之后。在这里项目里,我想的是采用在写完一个具体功能之后再写单元测试。第四步,学习如何将java project 打包成exe文件,这部分的知识对我来说也是一个新的知识,所以也需要时间进行学习。

所有资料: https://blog.csdn.net/qq_39615545/article/details/77244134 (Java文件与字节流操作)

https://blog.csdn.net/java958199586/article/details/6943033(Java流与文件操作)

http://www.cnblogs.com/yichenglongblog/p/8608408.html     (题目参考资料)

https://blog.csdn.net/sunkun2013/article/details/13167099  (文件打包参考资料)

3. 程序设计实现

(1)项目的总体结构

描述:整个项目是在eclipse下建立了一个java project项目然后创建了两个java类,分别为主函数类(MainCount)和功能类(WordCount),主函数类通过调用功能函数类,从控制台接受 了用户输入的指令后,将指令进行解析,然后再对解析的指令调用相对应的WordCount类中的方法进行处理,从而实现程序的功能。

(2) 类的详细设计:

WordCount类:

         

描述:charCount、lineCount、wordCount这三个整型变量分别用来存储最后统计出的总字符数、总行数和总单词数。

outResult这个字符型变量用来存储最后的字符串结果。

LineCommand统计总行数方法,传入参数文件路径集合,得到统计出的总行数。

CharCommand统计字符方法,传入参数文件路径集合,得到统计出的字符数。

wordCommand统计单词方法,传入参数文件路径集合,得到统计出的单词数。

OutputFile输出文件方法,传入参数输出的文本文件和查询结果。

MainCount类:

描述:main()函数是怎么程序执行的主函数,里面含有一个args[],在该数组里包含了用户在cmd命令行里输入的命令,各个命令以空格为斩断的形式,存入数组。该函数也是通过遍历命令数组,得到指令从而去调用WordCount里面所对应的方法。

(3) 类间关系图:

4. 代码实现

首先介绍一下四个功能的具体实现:

  • CharCommand方法

统计字符数方法,运用java对文件操作的技术,将指定的文件读出来然后一行一行的读取字符并计数。

//统计总字符
public String CharCommand(Set<String> file_paths)
{
outResult = "";
int bytes = 0;
byte[] temp = new byte[20*1024];//用于存储所读取的数据的字节数组 FileInputStream in = null; //文件字符输入流对象
try {
for(String file_path:file_paths)//遍历文件集合
{
in = new FileInputStream(file_path);//实例化文件字符输入流对象
while((bytes = in.read(temp, 0, temp.length))!=-1)//得到文件中的所有字符
{
charCount += bytes;//统计累计的字符数
} outResult += file_path+", 字符数:"+charCount+" ";//拼接字符串用于得到最后的输出结果
charCount = 0;
}
}catch(FileNotFoundException e)
{
e.printStackTrace();
}catch(IOException e)
{
e.printStackTrace();
}finally {
try {
in.close();
}catch(IOException e)
{
e.printStackTrace();
}
} return outResult;
}
  • LineCommand方法

统计行数方法,此方法的实现比较简单,也是运用java对文件操作的技术,将指定的文件读出来然后读一行就计数。

//统计总行数
public String LineCommand(Set<String> file_paths)
{
outResult = ""; //用于输出最后的统计结果
FileInputStream in = null; //声明字符输入流
InputStreamReader isr = null; //声明字节输入流
BufferedReader bdr = null; //声明缓存文本读取 try { for(String file_path:file_paths)//遍历路径集合中的每一项
{ in = new FileInputStream(file_path);//实例化文件字符输入流对象
isr = new InputStreamReader(in);//实例化字节输入流对象
bdr = new BufferedReader(isr);//实例化缓存输入流对象
while(bdr.readLine()!=null) //一次读取一行的字符
{
lineCount++; //统计累计的行数
} outResult += file_path+", 行数:"+lineCount+" ";//拼接字符串用于得到最后的输出结果
lineCount = 0;//可能多次调用,所以需要初始化
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e)
{
e.printStackTrace();
}
finally {
try {
in.close();
isr.close();
bdr.close();//关闭流操作
}catch(IOException e)
{
e.printStackTrace();
}
}
return outResult;
}
  • wordCommand方法

统计单词数方法,在统计单词数的时候,有一个明确的限制条件就是只能以空格和逗号作为判断单词的标准,所以这里还需要用到正则表达式 同时与需要运用java对文件操作的技术,大体的思路与实现字符计数差不多,就在每一行读出后用split方法分割字符串 。

//统计有多少个单词
public String wordCommand(Set<String> file_paths)
{
outResult = "";
StringBuffer sb = new StringBuffer();//用StringBuffer来进行读取的添加
String temp = "";//缓存字符串
FileInputStream in = null; //声明字符输入流
InputStreamReader isr = null; //声明字节输入流
BufferedReader bdr = null; //声明缓存文本读取 try {
for(String file_path:file_paths)
{
in = new FileInputStream(file_path);
isr = new InputStreamReader(in);
bdr = new BufferedReader(isr);
while((temp = bdr.readLine())!= null)//readLine()会返回字节数
{
sb.append(temp);//将读出的数据接在已经保存的数据后面
}
temp = sb.toString();
String[] totalWord = temp.split("[\\s+,\\.\n]");//用正则表达式将字符串按单词格式分开,空格和逗号
wordCount = totalWord.length;//所获取的数组长度就是单词个数 outResult += file_path+", 单词数:"+wordCount+" ";//拼接字符串用于得到最后的输出结果
wordCount = 0;
}
}catch(FileNotFoundException e)
{
e.printStackTrace();
}catch(IOException e)
{
e.printStackTrace();
}finally {
try {
in.close();
isr.close();
bdr.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
return outResult;
}
  • OutputFile方法

文件输出方法,将文件的输出路径和文件所要存储的内容作为函数的参数。创建相应的文件输出流对象和将content内容转换为byte字节

//输出到文件
public boolean OutputFile(String File_path,String Content)
{
File outputFile = new File(File_path);//创建一个输出文件的对象
FileOutputStream os = null; //声明文件输出流
byte[] test = null; //存储content转化的byte字节数组 if(!outputFile.exists())
{
try {
outputFile.createNewFile(); //如果输出文件不存在,则需要创建一个新文件
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
os = new FileOutputStream(outputFile);
test = Content.getBytes();
os.write(test);
System.out.println("\n");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e)
{
e.printStackTrace();
}finally {
try {
os.close();
}catch(IOException e)
{
e.printStackTrace();
}
} return true;
}

再来介绍一下MainCount类里的主函数:

  •  main()方法

           首先我们需要知道的是,用户输入的命令是会存储在main方法里面的一个参数String[] args数组里的,所以我们要做的事情,就是解析这个数组。看用户放了什么东西在里面,自然就会涉及到遍历的操作,遍历怎么数组。还需要知道的一点是,当用户没有指定将输出文件的时候,我们需要将输出的内容放在放在result.txt里面。

public static void main(String[] args)
{
WordCount WC = new WordCount();//实例化所需要的功能类
Set<String> file_paths = new HashSet<String>();//存储输入文件的集合
String outputFile = "result.txt"; //在默认的情况下输出的文本文件
String Result = ""; //显示查询的结果
int len = args.length; //命令长度 boolean isChar = false;//用于判断是否有统计字符数命令
boolean isLine = false;//用于判断是否有统计行数命令
boolean isWord = false;//用于判断是否有统计单词数命令 for(int i = 0;i < len;i++)
{
if(args[i].startsWith("-"))//判断命令中出现了那些指令
{
switch(args[i])
{
case "-c":
isChar = true;
break;
case "-l":
isLine = true;
break;
case "-w":
isWord =true;
break;
case "-o":
if(!args[i+1].startsWith("-"))//用于判断后面是否指定了具体的输出文件
{
outputFile = args[i+1];
i++;
}
else
{
System.out.println("error!");
System.exit(0);
}
break;
default:
System.out.println("error !");
break;
}
}
else
file_paths.add(args[i]);//将不属于命令的字符串存储在集合里
}
if (isWord) {
Result += WC.wordCommand(file_paths)+"\r\n";//调用统计单词数方法
}
if (isLine) {
Result += WC.LineCommand(file_paths)+"\r\n";//调用统计行数方法
}
if (isChar) {
Result += WC.CharCommand(file_paths)+"\r\n";//调用统计字符数方法
}
System.out.println(Result);
WC.OutputFile(outputFile, Result);
}

5. 测试设计过程

首先,我在设计的时候,想到了在上《构建之法》这门课时,学到的单元测试和回归测试。在每完成一个功能之后,都应该编写一个对应的测试方法,对功能进行测试。所有我在这里新建了一个test包,里面新建了一个UnitTest类用来进行单元测试。我在设计过程中的思路是:首先当用户的所输入的文件存在时是否可以运行,不存在时会不会运行。然后就是可能存在高风险的地方是在字符、行数、单词的计数上面。

下面是我的测试代码的设计:

public class UnitTest {
public static void testCharCommand()//测试统计字符数函数
{
Set<String> file_paths = new HashSet<String>();
String file1 = "E://file.c";//存在文件
String file2 = "E://file2.c";//不存在文件
file_paths.add(file1);
file_paths.add(file2);
System.out.println(new WordCount().CharCommand(file_paths));
} public static void testLineCommand()//测试统计行数函数
{ Set<String> file_paths = new HashSet<String>();
String file1 = "E://file.c";//存在文件
String file2 = "E://file2.c";//不存在文件
file_paths.add(file1);
file_paths.add(file2);
System.out.println(new WordCount().LineCommand(file_paths));
}
public static void testwordCommand()//测试统计总单词数函数
{ Set<String> file_paths = new HashSet<String>();
String file1 = "E://file.c";//存在文件
String file2 = "E://file2.c";//不存在文件
file_paths.add(file1);
file_paths.add(file2);
System.out.println(new WordCount().wordCommand(file_paths));
}
public static void testOutputFile()
{
String file_path = "result.txt";
String content = "OutputFileTESR";
System.out.println(new WordCount().OutputFile(file_path, content));
}
public static void main(String[] args) {
// TODO Auto-generated method stub
testCharCommand();
testLineCommand();
testwordCommand();
testOutputFile();
}
}

最后就是我的wc.exe 文件的测试过程,但是我只设置了一个测试用例。

  • -c命令测试:

默认生成的result.txt文件:

  • -l命令测试:

默认生成的result.txt文件:

  • -w命令测试:

默认生成的result.txt文件:

  • 多命令查询:

          

生成的指定文件filetest.txt:

6. 参考文献说明

1.关于PSP文件的书写:http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html

2.源代码管理:http://www.cnblogs.com/xinz/p/5044037.html

3.作业相关知识参考博客:http://www.cnblogs.com/oldBook/p/8592748.html

http://www.cnblogs.com/yichenglongblog/p/8608408.html

https://www.cnblogs.com/Who-Named-Cody/p/8609924.html

三、项目总结:


对于此项目,我只实现了项目所要求的基本功能。在分析过项目的需求后,我发现这些功能虽然看似很简单,但是做起来的工作其实也是很大的,我总结了以下几个原因:一、因为我之前没有深入地学习过java语言,只学习过java语言的基础语法,平时使用java语言做项目也很少。所以在这次项目中,对文件的操作也不是很熟悉,在开始编码之前,我需要对java语言对文件操作这一部分知识进行学习。二、此项目除了对编码有要求以外,还要结合《构建之法》这本书中所讲到关于在软件开发过程中,需要涉及到的软件工程的知识。另外还要撰写PSP表格、需求分析、测试用例、撰写博客。因此整个项目也不是单纯地实现功能那么简单了。并且我知道我的项目也存在了一些不足的地方,例如没有合理的安排我的时间,使得最后做项目的时候有点赶时间,不细致!一个合格软件开发人员,在此次作业中psp表内的内容应该都要做到,所以怎么安排自己时间是件很重要的事。除此之外,我认为还有我自己项目经验不足的原因。

通过本次项目,我收获颇丰。首先,学会了如何使用git管理自己的代码,以及如何通过git将自己的代码上传到码云上面。其次,学会了将自己的源代码程序打包成exe可执行文件,还体会了自己编写单元测试。然后,学习了撰写博客的经验,并实践到自己的博客中。最后,希望自己能够通过学习,使得自己的专业知识能力获得提升,并将自己的思路清晰的展现到博客中去。

     

个人项目———Java实现WordCount的更多相关文章

  1. Storm系列(三):创建Maven项目打包提交wordcount到Storm集群

    在上一篇博客中,我们通过Storm.Net.Adapter创建了一个使用Csharp编写的Storm Topology - wordcount.本文将介绍如何编写Java端的程序以及如何发布到测试的S ...

  2. Spark:用Scala和Java实现WordCount

    http://www.cnblogs.com/byrhuangqiang/p/4017725.html 为了在IDEA中编写scala,今天安装配置学习了IDEA集成开发环境.IDEA确实很优秀,学会 ...

  3. maven项目Java resources 上面有个红叉但是代码里面并没有什么报错

    maven项目Java resources 上面有个红叉但是代码里面并没有什么报错 解决办法: 1.通过: windows菜单  ->   show view/other 菜单  -> o ...

  4. 在IDEA中关于项目java版本问题

    在IDEA中关于项目java版本问题 当出现错误如:java无效的源发行版11或IDEA Error:java:Compliation failed:internal java complier er ...

  5. Eclipse导入项目java文件中文乱码

    感谢大佬:https://blog.csdn.net/ordinaryprogrammerc/article/details/83013710 本文链接:https://blog.csdn.net/o ...

  6. Java实现WordCount

    GitHub项目地址:https://github.com/happyOwen/SoftwareEngineering wordcount项目要求: 程序处理用户需求的模式为:wc.exe [para ...

  7. 软件工程:java实现wordcount基本功能

    github链接:https://github.com/Nancy0611/wc 一:项目相关要求 该项目能统计文本文件的字符数.单词数和行数.这个项目要求写一个命令行程序,模仿已有wc.exe 的功 ...

  8. java实现wordCount的map

    打开IDEA,File--new --Project,新建一个项目 我们已经安装好了maven,不用白不用 这里不要选用骨架,Next.在写上Groupid,Next. 写上项目名称,finish.o ...

  9. 异常处理_Maven之web项目java.lang.LinkageError

    浏览器运行项目异常如下: HTTP Status 500 - type Exception report message description The server encountered an i ...

随机推荐

  1. 安装本地 jar 文件

    Maven 提供了 maven-install-plugin 可将 jar 文件安装至本地 repository.安装命令如下: mvn install:install-file -Dfile= -D ...

  2. 【转帖】K8S Deployment 命令

    K8S Deployment 命令 https://www.cnblogs.com/Tempted/p/7831604.html 今天学习了一下 kubectl scale deployment xx ...

  3. [Xamarin] - 连接 Mac Agent 显示 "couldn't connect to xxxx, please try again" 之解决

    背景 在 VS 2017 的 Xamarin 项目中,配置 Mac Agent 连接到本地虚拟机中的 MacOS 失败. 1. MacOS 已启用远程登陆.2. SSH 可以登陆成功.3. 防火墙已关 ...

  4. xsy 2414【CF587C】Duff in the Army

    Description [题目描述]: 最近有一场战争发生,Duff是战争里一名士兵,Malek是她的长官. 他们的国家——Andarz Gu有n个城市(编号为1到n),总共有n-1条道路,每条道路连 ...

  5. php创建生成数组的相关函数

    php中和数组创建生成的函数有很多,用于定义数组的函数array(),数组合并函数array_combine(),还有array_fill(),array_fill_keys(),range()等等. ...

  6. Python中的if语句——参考Python编程从入门到实践

    条件测试 1. 检查是否相等 一个等号表示赋值,两个等号用于判断等号左右两边是否相等,返回值为True或者False. 2. 检查是否相等是需考虑大小写 大小写不同的值视为不相等,例如继续写入代码:c ...

  7. 机器学习-EM算法-GMM模型笔记

    GMM即高斯混合模型,下面根据EM模型从理论公式推导GMM: 随机变量X是有K个高斯分布混合而成,取各个高斯分布的概率为φ1,φ2,... ,φK,第i个高斯分布的均值为μi,方差为Σi.若观测到随机 ...

  8. MySQL中的case when 中对于NULL值判断的坑

    sql中的case when 有点类似于Java中的switch语句,比较灵活,但是在Mysql中对于Null的处理有点特殊 Mysql中case when语法: 语法1: CASE case_val ...

  9. 如何加入 Skype for Business 会议?

    参加一个线上培训,收到了Skype的参会地址,是这个样子的 然后就是一脸懵逼的不知道怎么参加会议了.找了半天终于在同事的帮助下参加成功. 我的参加方法:在Window上用Skype for Busin ...

  10. ubuntu下安装软件时报错解决:Unmet dependencies. Try 'apt-get -f install' with no packages

    在错误后面运行以下代码,补全依赖项: sudo apt-get -f install