首页 > 编程语言 > 详细

个人项目---WordCount实现(Java)

时间:2020-03-22 17:29:18      阅读:63      评论:0      收藏:0      [点我收藏+]

GitHub

一、项目简介

项目要求

wc.exe 是一个常见的工具,它能统计文本文件的字符数、单词数和行数。这个项目要求写一个命令行程序,模仿已有wc.exe 的功能,并加以扩充,给出某程序设计语言源文件的字符数、单词数和行数。

实现一个统计程序,它能正确统计程序文件中的字符数、单词数、行数,以及还具备其他扩展功能,并能够快速地处理多个文件。
具体功能要求:
程序处理用户需求的模式为:

wc.exe [parameter] [file_name]

功能列表

基本功能

-c file.c //返回文件 file.c 的字符数

-w file.c //返回文件 file.c 的词的数目

-l file.c //返回文件 file.c 的行数

扩展功能

-s 递归处理目录下符合条件的文件。
-a 返回更复杂的数据(代码行 / 空行 / 注释行)。

二、PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 40 40
· Estimate · 估计这个任务需要多少时间 500 655
Development 开发 430 490
· Analysis · 需求分析 (包括学习新技术) 100 120
· Design Spec · 生成设计文档 30 30
· Design Review · 设计复审 (和同事审核设计文档) 20 20
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 10
· Design · 具体设计 20 25
· Coding · 具体编码 200 200
· Code Review · 代码复审 20 30
· Test · 测试(自我测试,修改代码,提交修改) 30 25
Reporting 报告 40 55
· Test Report · 测试报告 15 20
· Size Measurement · 计算工作量 10 15
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 15 20
合计 510 655

三、思路

因为之前学过Java,当即决定了实现项目所要使用的语言。因为要实现读取文件的操作,加之之前对文件io之类的使用较少,故重新去熟悉了一下Java的io流。
先从实现项目的基本功能开始,一步一步慢慢实现。其本质就是对文件的读取内容进行解析。

四、设计实现过程

根据需求对功能进行分割,一共有五个功能,分别为:
  • -c 获取字符数
  • -w 获取单词数
  • -l 获取文件行数
  • -a 获取文件空行,注释行,代码行三种数据
  • -s 递归文件目录的操作,后面需接上面四类操作数

故将其分割为五个方法,每种方法进行一种操作。

项目共有四个类,分别为:

Main------------------------主程序入口
GetFileInputStream----------对文件的io操作
WC---------------------------wc实体类,记录各个数据
WordCount-------------------各种获取方法的功能就在这个类里面

执行流程如下:

技术分享图片
技术分享图片

五、代码说明

文件读取操作
  • 使用缓冲流BufferedReader来读取文件效率更好
public static BufferedReader getFileInputStream(String fileName) {
        BufferedReader bufferedReader = null;
        File file = new File(fileName);
        if (file.exists()){
            try {
                bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));

            } catch (FileNotFoundException e) {
                e.printStackTrace();
                System.out.println("该路径文件不存在!");
            }
        }else{
            System.out.println("该路径或文件不存在!");
            return null;
        }
        return bufferedReader;
    }
获得文件单词数------ -w 操作
   /**
     * 获得单词数------  -w 操作
     * @param fileName 操作文件名
     * @return 返回单词数
     */
    public static int getWordCount(String fileName){
        int count1 = 0;
        BufferedReader bufferedReader01 = GetFileInputStream.getFileInputStream(fileName);
        if(bufferedReader01 == null){
            return -1;
        }
        try {
            String str = null;
            //获得每行的数据,将这一行数据分隔开存入数组中,每行数组个数相加即为单词个数
            while((str=bufferedReader01.readLine())!=null){
                String oneLine[] = str.split("\\s");
                count1+=oneLine.length;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedReader01.close(); //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return count1;
    }
获得文件字符数----- -c 操作
    /**
     * 获得字符数----- -c 操作
     * @param fileName 操作文件名
     * @return 返回字符数
     */
    public static int getCharCount(String fileName){
        int count2 = 0;
        BufferedReader bufferedReader02 = GetFileInputStream.getFileInputStream(fileName);
        if(bufferedReader02 == null){
            return -1;
        }
        String str;
        try {
            //循环读取字符,直到流结束
            while((str = bufferedReader02.readLine())!=null){
                //每次读取一行后将字符串转化成字符数组,每次将字符数组的值相加即得字符的总数
                char c[] = str.toCharArray();
                count2+=c.length;
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭流
                bufferedReader02.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return count2;
    }
获得文件行数----- -l 操作
   /**
     * 获得行数----- -l 操作
     * @param fileName 操作文件名
     * @return 返回行数
     */
    public static int getLineCount(String fileName){
        int count3 = 0;
        BufferedReader bufferedReader03 = GetFileInputStream.getFileInputStream(fileName);
        if(bufferedReader03 == null){
            return -1;
        }
        try {
            //是否有下一行
            while(bufferedReader03.readLine()!=null) {
                count3++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭流
                bufferedReader03.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return count3;
    }
获得空行、注释行、代码行----- -a 操作
    /**
     * 获得空行、注释行、代码行----- -a 操作
     * @param fileName 操作文件名
     * @return 返回wc对象,对象中包含三个复杂数据
     */
    public static WC getThreeCount(String fileName){
        BufferedReader br = GetFileInputStream.getFileInputStream(fileName);
        WC wc = new WC();
        int spaceCount = 0;
        int nodeCount = 0;
        int codeCount = 0;
        //判断是否为多行注释的标志
        boolean flag = false;
        if(br==null){
            return null;
        }
        try {
            String s1 = null;
            String s2 = null;
            while((s1=br.readLine())!=null){
                if (flag){
                    if (s1.endsWith("*/")){
                        flag = false;
                    }
                    nodeCount++;//注释行+1
                }else {
                    s2 = s1.replaceAll("\\s","");
                    if ("".equals(s2)){
                        spaceCount++;
                    }else if (s2.startsWith("//")||s2.startsWith("}//")){
                        nodeCount++;
                    }else if (s2.startsWith("/*")){
                        if (!s2.endsWith("*/")){
                            //不是单行注释,标志置为真
                            flag = true;
                        }
                        nodeCount++;
                    }else {
                        codeCount++;
                    }
                }
            }
            wc.setNodeCount(nodeCount);
            wc.setSpaceCount(spaceCount);
            wc.setCodeCount(codeCount);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //关闭流
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return wc;
    }
遍历文件夹下所有目录,包括子目录
   /**
     * 遍历文件夹下所有目录,包括子目录
     * @param path 路径
     * @param fileList 文件列表
     */
    public static void getFileList(String path,List<String> fileList){
        File file = new File(path);
        if (file.exists()){
            if (file.isDirectory()){
                File[] files = file.listFiles();
                if (null == files||files.length == 0){
                    System.out.println("此目录为空!");
                    return ;
                }else {
                    for (File f:files) {
                        if (f.isDirectory()){
                            getFileList(f.getAbsolutePath(),fileList);
                        }else {
                            fileList.add(f.getAbsolutePath());
                        }
                    }
                }
            }else{
                System.out.println("这个不是目录路径!");
            }
        }else {
            System.out.println("此路径不存在!");
        }
    }

六、测试运行

空文件

技术分享图片
技术分享图片

单个字符

技术分享图片
技术分享图片

一个单词

技术分享图片
技术分享图片

一行多个单词

技术分享图片
技术分享图片

多行文件

技术分享图片
技术分享图片

代码文件(含注释)

技术分享图片
技术分享图片

递归目录

技术分享图片
技术分享图片

错误输入

技术分享图片

七、总结

  1. 实际花费时间比预计时间多了很多,主要是在对以前学过的一些知识点没那么熟悉,需要回去查询资料加深认识
  2. 熟悉了进行一个个人项目所需要的流程和步骤,明白了要做好计划,跟着计划来执行效率会更好
  3. 一些功能还没有做好,比如文件通配符和图形化界面,后续如果有时间的话会继续去完善它
  4. 对功能的需求要考虑好后续的使用和迭代,另外要注意代码简洁性

个人项目---WordCount实现(Java)

原文:https://www.cnblogs.com/lyx708194/p/12546696.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!