WordCount--统计输入文件的字符数、行数、单词数(java)--初级功能

码云地址:

https://gitee.com/YuRenDaZ/WordCount

个人PSP表格:

PSP2.1

PSP阶段

预估耗时

(分钟)

实际耗时

(分钟)

Planning

计划

 180

 120

· Estimate

· 估计这个任务需要多少时间

 180

 120

Development

开发

 580

 440

· Analysis

· 需求分析 (包括学习新技术)

 180

 60

· Design Spec

· 生成设计文档

 40

 30

· Design Review

· 设计复审 (和同事审核设计文档)

 20

 20

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 20

 10

· Design

· 具体设计

 20

 20

· Coding

· 具体编码

 180

 200

· Code Review

· 代码复审

 30

 40

· Test

· 测试(自我测试,修改代码,提交修改)

 90

 60

Reporting

报告

 90

 70

· Test Report

· 测试报告

 40

 30

· Size Measurement

· 计算工作量

 20

 10

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 30

 30

 

合计

 850

 630

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

一、功能需求分析

  WordCount的需求可以概括为:对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。可执行程序命名为:wc.exe,该程序处理用户需求的模式为:

wc.exe [parameter] [input_file_name]

存储统计结果的文件默认为result.txt,放在与wc.exe相同的目录下。

详细分析:

 功能 -c   :返回文件 file.c 的字符数

 功能 -w   :返回文件 file.c 的单词总数

 功能 -l     :返回文件 file.c 的总行数

 功能 -o    :将结果输出到指定文件outputFile.txt

 要求 : 1. -o 功能后面必须有输出文件路径的参数。

    2.在没有 -o 命令指定输出文件的时候默认将结果保存在exe同目录下的result.txt。

    3.可以满足多个文件同时查询。

注意:

空格,水平制表符,换行符,均算字符。

由空格或逗号分割开的都视为单词,且不做单词的有效性校验,例如:thi#,that视为用逗号隔开的2个单词。

 

二、程序设计

A:大概设计

    1):程序由工具类和主函数类构成。

       2):程序使用main的入口参数。

B:详细设计

  1):将每一个“-?”指令对应一个方法。

     2):将功能方法写在一个类里,作为工具类。

     3):使用条件判断语句来处理命令。

     4):用集合存储需要查询的文件,以方便进行添加和遍历。

     5):程序主要逻辑在main函数中进行。(逻辑并不非十分复杂)

三、程序编码(编码并不是最好的实现方法,希望各位同学能指出不足之处,我们大家一起进步!)

  • 主函数逻辑主要是由循环语句和条件判断语句完成。代码如下:
     1 import java.util.HashSet;
     2 import java.util.Set;
     3 
     4 public class WordCount {
     5     
     6     public static void main(String[] args) {
     7         CountUtil countUtil = new CountUtil();//实例化工具类对象
     8         Set<String> file_paths = new HashSet<String>() ; //创建用于存储输入文件的集合
     9         String Output_file = "result.txt"; //存储输出文件名(默认为同目录下的result.txt文件)
    10         String Result = ""; //存储查询结果
    11         boolean isCharacters = false; //是否查询字符数
    12         boolean isLines = false; //是否查询行数
    13         boolean isWords = false; //是否查询单词数
    14         for (int i = 0;i<args.length;i++) { //循环读取入口参数
    15             if (args[i].startsWith("-")) { //判断是否是命令
    16                 switch (args[i]) {
    17                 case "-c":
    18                     isCharacters = true; //是-c指令,激活查询条件
    19                     break;
    20                 case "-l":
    21                     isLines = true; //是-l指令,激活查询条件
    22                     break;
    23                 case "-w":
    24                     isWords =true; //是-w指令,激活查询条件
    25                     break;
    26                 case "-o":
    27                     if(!args[i+1].startsWith("-")) //-o指令 判断后面是否有指定输出文件
    28                     {
    29                         Output_file = args[i+1]; //args[i+1]必须为输出文件
    30                         i++;
    31                     }else {
    32                         System.out.println("input error !"); //提示输入错误并终止程序
    33                         System.exit(0);
    34                     }
    35                     break;
    36                 default:
    37                     System.out.println("input error !");
    38                     break;
    39                 }
    40             }
    41             else file_paths.add(args[i]); //将不属于命令的字符串存储在集合里面
    42         }
    43         
    44         if (isWords) {
    45             Result+=countUtil.ReturnWords(file_paths)+"\r\n"; //调用查询单词方法,并做字符串拼接
    46         }
    47         if (isLines) {
    48             Result+=countUtil.ReturnLines(file_paths)+"\r\n"; //调用查询行数方法,并做字符串拼接
    49         }
    50         if (isCharacters) {
    51             Result+=countUtil.ReturnCharacters(file_paths)+"\r\n"; //调用查询字符数方法,并做字符串拼接
    52         }
    53             System.out.println(Result);
    54             countUtil.OutputFile(Output_file, Result); //将结果输出到文件
    55     }
    56 }

     

  • 在工具类中各方法的实现:(基本上都是基于IO流的操作)

  ReturnCharacters方法,返回查询结果(String类型),参数为输入文件的集合。代码如下:

public String ReturnCharacters(Set<String> file_paths) {int Count = 0,bytes = 0;String result = "";//用于存储返回值byte [] tem = new byte[20*1024];//用存储读取数据的定常字节数组int len = tem.length;//得到tem的长度以避免循环时反复调用.lengthFileInputStream in = null;//声明一个文件输入流try {for (String file_path : file_paths) {in = new FileInputStream(file_path);//得到字符输入流,string为文件绝对路径         while ((bytes = in.read(tem,0,len))!=-1) {Count+=bytes;//统计累计读取的字符数
                }result += file_path+",字符数:"+Count+"    ";//结果字符串拼接Count = 0;}    } catch (FileNotFoundException e) {System.out.println("有文件输入错误,请核对!(如果不会使用相对路径,请使用绝对路径)"); //检查到文件不存在,提示错误System.exit(0); //结束程序} catch (IOException e) {e.printStackTrace();}finally {try {in.close();//关闭输入流} catch (IOException e) {e.printStackTrace();}}return result;}
返回字符数

  ReturnWords方法,返回查询结果(String类型),参数为输入文件的集合。代码如下:

 1     public String ReturnWords(Set<String> file_paths){
 2         int Count = 0; //存储单词数
 3         String result = "";//存储返回值
 4         StringBuffer saveString = new StringBuffer();//因为string具有不可变性,用StringBuffer来进行读取的添加
 5         String tmp = ""; //缓存字符串
 6         FileInputStream in = null;//声明文件字符输入流
 7         InputStreamReader isr = null;//声明字节输入流
 8         BufferedReader bis = null;//声明缓存输入流
 9         try {
10             for (String file_path : file_paths) {   //foreach循环遍历数组
11                 in = new FileInputStream(file_path);//实例化文件输入流对象
12                 isr = new InputStreamReader(in);//实例化字节输入流对象
13                 bis = new BufferedReader(isr);//实例化缓存输入流对象
14                 while ((tmp=bis.readLine())!=null) { //readLine()返回读取的字节,若没有了就返回null
15                     saveString.append(tmp); //将新读出来的数据接在已保存的后面
16                 }
17                 tmp = saveString.toString(); //用字符串存储,以用split方法区分单词
18                 String [] total = tmp.split("[\\s+,\\.\n]");//用正则表达式将字符串按单词格式分开
19                 Count = total.length; //字符串数组长度就是单词个数
20                 result += file_path+",单词数:"+Count+"    "; //结果字符串拼接
21                 Count = 0;
22             }
23         } catch (FileNotFoundException e) {
24             System.out.println("有文件输入错误,请核对!(如果不会使用相对路径,请使用绝对路径)"); //检查到文件不存在,提示错误
25             System.exit(0); //结束程序
26         } catch (IOException e) {
27             e.printStackTrace();
28         }finally {
29             try {
30                 in.close();//关闭文件字符输入流
31                 isr.close();//关闭字节输入流
32                 bis.close();//关闭缓存输入流
33             } catch (IOException e) {
34                 e.printStackTrace();
35             }
36             
37         }
38         return result;
39     }
返回单词数

  ReturnLines方法,返回查询结果(String类型),参数为输入文件的集合。代码如下:

 1 public String ReturnLines(Set<String> file_paths) {
 2         int Count = 0;
 3         String result = "";
 4         FileInputStream in = null;//声明文件字符输入流
 5         InputStreamReader isr = null;//声明字节输入流
 6         BufferedReader bis = null;//声明缓存输入流
 7         try {
 8             for (String file_path : file_paths) {   //foreach循环遍历数组
 9                 in = new FileInputStream(file_path);//实例化文件输入流对象
10                 isr = new InputStreamReader(in);//实例化字节输入流对象
11                 bis = new BufferedReader(isr);//实例化缓存输入流对象
12                 while (bis.readLine()!=null) {
13                     Count++;
14                 }
15                 result += file_path+",行数:"+Count+"    "; //结果字符串拼接
16                 Count = 0;
17             }
18         } catch (FileNotFoundException e) {
19             System.out.println("有文件输入错误,请核对!(如果不会使用相对路径,请使用绝对路径)"); //检查到文件不存在,提示错误
20             System.exit(0); //结束程序
21         } catch (IOException e) {
22             e.printStackTrace();
23         }finally {
24             try {
25                 in.close();//关闭文件字符输入流
26                 isr.close();//关闭字节输入流
27                 bis.close();//关闭缓存输入流
28             } catch (IOException e) {
29                 e.printStackTrace();
30             }
31             
32         }
33         return result;
34     }
返回行数

  OutputFile方法,将结果保存在文件中,返回boolean型,参数为文件路径和内容。代码如下:

 1     public boolean OutputFile(String File_path,String Context){
 2         File OutputFile = new File(File_path); //创建File对象
 3         FileOutputStream os = null; //声明 文件输出流
 4         byte [] a = null; //用于存储Context转化的byte字节数组
 5         try {
 6             if(!OutputFile.exists()) {        //判断文件是否存在
 7                     OutputFile.createNewFile(); //不存在,创建一个文件
 8             }
 9             os = new FileOutputStream(OutputFile); //获得输出流对象
10             a = Context.getBytes(); //将Context转化为Byte数组,以便写入文件
11             os.write(a); //将byte数组写入文件
12         } catch (IOException e) {
13             e.printStackTrace();
14         }finally {
15             try {
16                 os.close(); //关闭输出流
17             } catch (IOException e) {
18                 e.printStackTrace();
19             }
20         }
21         return true;
22     }
23 }
输出结果文件

 

四、代码测试

  代码调试方法参照 https://www.cnblogs.com/xy-hong/p/7197725.html

由于是使用的main函数的入口参数,所以之前并未接触过这类方式的程序编写。在经过查阅后在改文章上找到了调试方式。具体操作再次不予详述,请参照以上链接。

     因为要求不能用已有得测试框架进行测试,所以就自己设计了一个测试类。在类中,分为单独针对每一个需要测试得方法都设计一个测试方法,然后再主函数中调用达到一次性全部测试得效果。

    

import java.util.HashSet;
import java.util.Set;public class ProTest {public static void main(String[] args) {testOutputFile();testReturnCharacters();testReturnLines();testReturnWords();}public static void testReturnCharacters() {Set<String> file_paths = new HashSet<String>();String file1 = "F://test.c";String file2 = "F://test.java";file_paths.add(file2);file_paths.add(file1);System.out.println("testReturnCharacters():");System.out.println(new CountUtil().ReturnCharacters(file_paths));}public static void testReturnWords() {Set<String> file_paths = new HashSet<String>();String file1 = "F://test.c";String file2 = "F://test.java";file_paths.add(file2);file_paths.add(file1);System.out.println("testReturnWords():");System.out.println(new CountUtil().ReturnWords(file_paths));}public static void testReturnLines() {Set<String> file_paths = new HashSet<String>();String file1 = "F://test.c";String file2 = "F://test.java";file_paths.add(file2);file_paths.add(file1);System.out.println("testReturnLines():");System.out.println(new CountUtil().ReturnLines(file_paths));}public static void testOutputFile() {String file_path  = "result.txt";String context = "OutPutFile test !";if(new CountUtil().OutputFile(file_path, context)) {System.out.println("File output success !");}else {System.out.println("error !");}}
}

 

直接运行测试类,得到结果:

  

 

用例测试:

      

文件中的结果:

      

 

 

 

 

 

 

五、将项目导出为exe可执行文件

  依赖工具:exe4j

     参考方法:手把手教你如何把java代码,打包成jar文件以及转换为exe可执行文件(注意:改博客中没有指出32位和64位系统的差别,具体如下)

          

六、项目与远程库同步过程(码云)

  有关git和码云项目的远程连接以及工作提交等相关操作参考Git和Github简单教程(该教程非常的详细,值得推荐。

    本项目一共有三次项目提交,分别是初始代码、复审代码、测试后修改的最终代码。

七、个人总结

  第一次撰写博客有很多迷茫之处,但是在撰写博客的过程中我发现这其实是对整个项目过程的一次回顾与反思。在以前的作业中,通常都是写完代码测试完后就不再关注,也不会反在完成项目的途中犯过什么样的错误。每当下次遇到同样的问题还是会被困扰住,所以我觉得写博客是真的有必要的。虽然写出来的博客没人看,没人会在意,但是这并不是开始学习的我们的目的。我们的目的就在于回顾过程,反思过程中的错误,让项目的过程在我们脑海里留下更深的印象。最后,这次的作业的量还是算比较大的,但是却真的能感觉到有很多的收获。很多东西都是词不达意的,真的用心体会过就能明白。

     感谢以上引用的各链接的作者们,希望你们的文章能帮助更多的人。

转载于:https://www.cnblogs.com/YuRenX/p/9693943.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/279289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

荣耀9igoogle模式_iGoogle个性化主页的6种替代方法

荣耀9igoogle模式iGoogle has less than a year to go before it’s shut down for good on November 1, 2013. While Google seems to think that iGoogle isn’t necessary anymore, there are other services waiting to take its place. iGoogle距离其2013年11月1日永久关闭…

华为堡垒机_安恒信息成为“华为云优秀严选合作伙伴”,携手保障“云上”资产安全访问...

加快5G持续创新能力&#xff0c;为云计算行业注入新动能。近日&#xff0c;以“智者•同行•共赢”为主题的2020华为云ISV(严选)合作伙伴大会在杭州隆重举行。上百位华为云合作伙伴、行业大咖等专业人士齐聚一堂&#xff0c;探讨云计算产业热门话题。作为华为云重要的生态合作伙…

非三星手机无法登录三星账号_如何解决所有三星手机的烦恼

非三星手机无法登录三星账号Samsung is the biggest manufacturer of Android phones in the world, but that doesn’t mean these handsets are perfect out of the box. In fact, most of these phones have several annoyances initially—here’s how to fix many of thes…

设置单元格填充方式_单元格的选择及设置单元格格式

数据输入完毕&#xff0c;接下来可以设置字体、对齐方式、添加边框和底纹等方式设置单元格格式&#xff0c;从而美化工作表。要对单元格进行设置&#xff0c;首先要选中单元格。选择单元格选择单元格是指在工作表中确定活动单元格以便在单元格中进行输入、修改、设置和删除等操…

springboot三种过滤功能的使用与比较

若要实现对请求的过滤&#xff0c;有三种方式可供选择&#xff1a;filter、interceptort和aop。本文主要讨论三种拦截器的使用场景与使用方式。 下文中的举例功能是计算每个请求的从开始到结束的时间&#xff0c;例子来源是慕课网。 一、filter 特点&#xff1a;可以获取原始的…

后缀的形容词_构词法(18)构成形容词的常见后缀 3

即时练习一、按要求改写下列单词。1. Japan →___________ adj. 日本(人)的2. Canton →_________ adj. 广东(人)的3. Vietnam →__________ adj. 越南(人)的4. Europe →__________ adj. 欧洲(人)的5. India → ________ adj. 印度(人)的6. Africa →_______ adj. 非洲(人)的7…

批量删除推文_如何搜索(和删除)您的旧推文

批量删除推文“The internet never forgets” is an aphorism that isn’t entirely true, but it’s worth thinking about whenever you post to social media. If you think your Twitter profile needs a bit of a scrub, here’s how to search and delete those old twee…

智能记忆功能nest_如何设置和安装Nest Protect智能烟雾报警器

智能记忆功能nestIf you want to add a bit more convenience and safety to your home’s smoke alarm setup, the Nest Protect comes with a handful of great features to make that a reality. Here’s how to set it up and what all you can do with it. 如果您想为您的…

网格自适应_ANSYS 非线性自适应(NLAD)网格划分及应用举例

文章来源&#xff1a;安世亚太官方订阅号&#xff08;搜索&#xff1a;Peraglobal&#xff09;在复杂的结构设计分析中&#xff0c;通常很难确定在高应力区域中是否生成适当的细化网格。在做非线性大应变分析仿真时&#xff0c;可能由于单元变形过大&#xff0c;导致网格畸变&a…

python---[列表]lsit

内置数据结构&#xff08;变量类型&#xff09; -list -set -dict -tuple -list&#xff08;列表&#xff09; -一组又顺序的数据组合 -创建列表 -空列表 list1 []        print(type(list1))        print(list1)        list2 [100]       …

唤醒计算机运行此任务_如何停止Windows 8唤醒计算机以运行维护

唤醒计算机运行此任务Windows 8 comes with a new hybrid boot system, this means that your PC is never really off. It also means that Windows has the permission to wake your PC as it needs. Here’s how to stop it from waking up your PC to do maintenance tasks…

转整型_SPI转can芯片CSM300详解、Linux驱动移植调试笔记

一口君最近移植了一款SPI转CAN的芯片CSM300A&#xff0c;在这里和大家做个分享。一、CSM300概述CSM300(A)系列是一款可以支持 SPI / UART 接口的CAN模块。1. 简介CSM300(A)系列隔离 SPI / UART 转 CAN 模块是集成微处理器、 CAN 收发器、 DC-DC 隔离电源、 信号隔离于一体的通信…

matlab练习程序(二值图像连通区域标记法,一步法)

这个只需要遍历一次图像就能够完全标记了。我主要参考了WIKI和这位兄弟的博客&#xff0c;这两个把原理基本上该介绍的都介绍过了&#xff0c;我也不多说什么了。一步法代码相比两步法真是清晰又好看&#xff0c;似乎真的比两步法要好很多。 代码如下&#xff1a; clear all; c…

pc微信不支持flash_在出售PC之前,如何取消对Flash内容的授权

pc微信不支持flashWhen it comes to selling your old digital equipment you usually should wipe it of all digital traces with something like DBAN, however if you can’t there are some precautions you should take–here’s one related to Flash content you may h…

绘制三维散点图_SPSS统计作图教程:三维散点图

作者&#xff1a;豆沙包&#xff1b;审稿&#xff1a;张耀文1、问题与数据最大携氧能力是身体健康的一项重要指标&#xff0c;但检测该指标成本较高。研究者想根据性别、年龄、体重、运动后心率等指标建立预测最大携氧能力的模型&#xff0c;招募了100名研究对象&#xff0c;测…

使用lodash防抖_什么,lodash 的防抖失效了?

戳蓝字「前端技术优选」关注我们哦&#xff01;作者&#xff1a;yeyan1996https://juejin.im/post/6892577964458770445应某人的要求被迫营业&#xff0c;望各位看官不要吝啬手中的赞-。-背景在使用 uni-app 开发小程序时&#xff0c;有个填写表单的需求&#xff0c;包含两个输…

Ubuntu 12.10中的8个新功能,Quantal Quetzal

Ubuntu 12.10 has been released and you can download it now. From better integration with web apps and online services to improvements in Unity, there are quite a few changes – although none of them are huge or groundbreaking. Ubuntu 12.10已发布&#xff0c…

背单词APP调研分析

前言&#xff1a;随着我国网络经济重心向移动端的转移&#xff0c;移动教育领域获得的关注度在持续放大。互联网的发展和移动设备的普及&#xff0c;我们开始在移动设备上学习&#xff0c;各种学习教育软件如雨后春笋&#xff0c;越来越多&#xff0c;就背单词软件来说&#xf…

cdh中使用hue使用教程_我可以在户外使用Philips Hue灯泡吗?

cdh中使用hue使用教程Philips Hue lights are great to have in your house, and they can add a lot of convenience to your living space. However, what if you want to use these smart bulbs outdoors in porch lights or flood lights? Will Philips Hue bulbs work pr…

弄断过河电缆_你说的是:剪断电缆线

弄断过河电缆Earlier this week we asked you if you’d cut the cable and switched to alternate media sources to get your movie and TV fix. You responded and we’re back with a What You Said roundup. 本周早些时候&#xff0c;我们问您是否要切断电缆并切换到其他媒…