个人项目 Word Count

Word Count

github地址:https://github.com/imenist/WordCount

一.项目要求

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

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

3.基本要求:

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

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

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

4.扩展功能:

    -s   递归处理目录下符合条件的文件

    -a   返回更复杂的数据(代码行 / 空行 / 注释行)。

5.高级功能:

   -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。

二.PSP表格

PSP2.1 Personal Software Process Stages 预估时间(分钟) 实际耗时(分钟)
Planning 计划 10 10
-Estimate -估计这个任务需要多少时间 265 400
Development 开发 250 400
-Analysis -需求分析(包括学习新技术) 20 20

-Design Spec

-生成设计文档 30 20
-Design Review -设计复审(和同事审核设计文档) 20 10
-Coding Standard -代码规范(为目前得开发制定合适得规范) 10 10
-Design -具体设计 30 80
-Coding -具体编码 90 200
-Code Review -代码复审 30 10
-Test -测试(自我测试,修改代码,提交修改) 20 50
Reporting 报告 50 60
-Test Report -测试报告 30 40
-Size Measurement -计算工作量 10 10
-Postmortem & Process Improvement Plan -事后总结,并提出过程改进计划 10 10
合计   310 470

三.解题思路

    1.基本要求:

  • 统计字符数:一行一行地读取文件内容,然后统计各行的字符数,再累加。
  • 统计单词数:一行一行读取文件,然后通过判断空格与字符的关系统计单词数,再累加。
  • 统计行数:一行一行读取文件,直接累加   

   2.进阶功能

  • 递归处理符合要求的文件:判断是否是文件还是文件夹,若是文件则返回,文件夹则继续递归直到找到文件,然后通过正则表达式筛选出符合要求的文件(一开始是想利用文件名的后缀名来进行简单的区分,然而这样不能够实现模糊搜索即匹配符,后来学习到使用正则表达式即可比较顺利的完成要求)
  • 统计复杂数据(代码行 / 空行 / 注释行):一行一行的读取文件,设置布尔变量,若满足条件则累加
  • 显示图形界面:调用java的Swing组建,进行控件布局的管理(一开始直接使用容器进行添加,发现运行的时候仅有最后一个添加的会显示出来,后来又找了许多文档以及查看了jframe的源码才找到问题所在,没有设置布局)

 四.设计实现过程

    1.主要类:

  • main:项目的主函数
  • wordCount:获得详细的数据,比如字符数,单词数等,作为对象返回
  • readFile:读取文件
  • travelFile:进行文件夹和文件的递归
  • count:wordCount底下的方法,其中有多个方法进行数据的获取
  • frameUI:进行gui界面的设计

  2.程序运行流程图:

   

五.代码说明

1.返回字符数目

public int getCharNum(String str){
        char[] cn = str.toCharArray();
        return cn.length;
    }

2.返回单词数目

public int getWordNum(String str){
        boolean flag = false;
        int num = 0;
        int length;
        char[] wn = str.toCharArray();
        length = wn.length;
        for(int i=0;i<length;i++){
            //当是一个新单词的时候才+1
            if(((wn[i]>=65 && wn[i]<=90) || (wn[i]>=97 && wn[i]<=122)) && flag == false){
                flag = true;
                num++;
            }else if((wn[i]>=65 && wn[i]<=90) || (wn[i]>=97 && wn[i]<=122)){
                //如果不是新单词就跳过
                continue;
            }else{
                //一个单词结束时就设为false
                flag = false;
            }
        }
        return num;
    }

 3.返回注释行数

public int getNoteLineNum(ArrayList<String> str){
        int num = 0;
        boolean flag = false;
        for(int i=0;i<str.size();i++){
            String temp = str.get(i).trim();
             //单行注释直接+1
            if(temp.startsWith("//"))
                num += 1;
            //多行注释,先+1并设置布尔变量,知道遇到*/才结束+1
            else if(temp.startsWith("/*")){
                num += 1;
                flag = true;
            }
            else if(temp.endsWith("*/")){
                num += 1;
                flag = false;
            }
            else if(flag == true)
                num += 1;
        }
        return num;
    }

4.递归处理文件

ArrayList<String> pathsFile = new ArrayList<String>();
                File file = new File(filesPath);
                //建立ft对象进行递归处理
                fileTravel ft = new fileTravel(pathsFile,sy);
                ft.travel(file);
                int length = pathsFile.size();
                //将得到的文件进行wordCount处理并输出
                for(int i=0;i<length;i++){
                    String currentFile = pathsFile.get(i);
                        wc.count(currentFile);
                        System.out.println("文件:"+currentFile);
                        switch (choose1){
                            case "-c" :System.out.println("文件字符数目:"+wc.getCharNum());break;
                            case "-w" :System.out.println("文件单词数目:"+wc.getWordNum());break;
                            case "-l" :System.out.println("文件行数:"+wc.getLineNum());break;
                            case "-a" :
                                System.out.println("文件字符数目:"+wc.getCharNum());
                                System.out.println("文件单词数目:"+wc.getWordNum());
                                System.out.println("文件行数:"+wc.getLineNum());
                                System.out.println("文件代码行数:"+wc.getCodeLine());
                                System.out.println("文件注释行数:"+wc.getNoteLine());
                                System.out.println("文件空行数:"+wc.getEmptyLine());
                                break;
                        }
                }
                break;


public class fileTravel {
    public ArrayList<String> filePaths;
    Matcher m ;
    String sy =null;

    public fileTravel(ArrayList<String> filePaths,String sy) {
        this.filePaths = filePaths;
        this.sy = sy;
    }
    public fileTravel(ArrayList<String> filePaths){
        this.filePaths = filePaths;
    }


    public void travel(File file){
        //通过正则表达式,进行通配符的查找并且筛选符合要求的文件(此处为txt文件)
        String sy1 = "^["+sy+"].*(.txt)$";
        Pattern p = Pattern.compile(sy1);
        if(file == null)
            return;
        m = p.matcher(file.getName());
        //当找到符合的文件时才将其放进文件的字符串数组中进行调用
        if(m.find() || sy == null)
          filePaths.add(file.getAbsolutePath());
        if(file.isDirectory()){
            for (File files:file.listFiles()){
                //当是文件夹时,继续进行递归
                travel(files);
            }
        }
    }
}

5.gui设计

public frameUI() {
        //获得Jframe对象
        jFrame = new JFrame();
        //设置标题
        jFrame.setTitle("Word Count");
        //设置窗口大小
        jFrame.setBounds(600,600,800,100);
        jFrame.setDefaultCloseOperation(jFrame.EXIT_ON_CLOSE);
        //获得窗口对象进行编辑
        jFrame.getContentPane().add(getContentPane());
        this.setLayout(new FlowLayout());


        //初始化窗口各控件参数
        JLabel label = new JLabel();
        label.setText("文件名称:");
        JButton button = new JButton("选择文件");
        JButton button1 = new JButton("选择文件夹");
        JButton _c = new JButton("-c");
        JButton _w = new JButton("-w");
        JButton _l = new JButton("-l");
        JButton _a = new JButton("-a");
        JButton _s = new JButton("-s");
        textField = new JTextField(20);

        //将各控件添加到窗口上
        getContentPane().add(label);
        getContentPane().add(textField);
        getContentPane().add(button);
        getContentPane().add(button1);
        getContentPane().add(_c);
        getContentPane().add(_w);
        getContentPane().add(_l);
        getContentPane().add(_a);
        getContentPane().add(_s);

//进行选择文件时,调用自带的fileChooser并获得文件对象,返回其路径于文本框中
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int i = fileChooser.showOpenDialog(getContentPane());
                if(i == JFileChooser.APPROVE_OPTION){
                    selectedFile = fileChooser.getSelectedFile().getAbsoluteFile();
                    textField.setText(selectedFile.getName());
                }
            }
        });

//选择_s函数时进行文件夹的递归,并自动将符合要求的文件以对话框的形式输出其数据
        _s.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String filePaths = selectedFile.getAbsolutePath();
                File currentFile = new File(filePaths);
                try {
                    fileTravelUI(currentFile);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        });

六.测试运行

1.基本功能

  • 空文件:

       

  • 只有一个字符的文件:

       

  •  只有一个单词的文件

      

  • 只有一行的文件

      

  • 一个典型的源文件

      

2.扩展功能(-a,-s)

    

   

            

3.高级功能(gui操作)

  • 选择单个文件进行基本操作

          

      

  • 选择文件夹进行递归

 

 

七.项目小结

      第一次做个人项目,许多地方都不太熟练,光是理解题目就使用了不少的时间。在这个过程中我也学习到了许多以前不知道的知识

  • 在文件筛选中,java的IO流搭配正则表达式可以处理绝大多数的文件筛选工作
  • 在gui设计中,不同布局间的优劣也学习到了不少
  • 在敲代码前,有一个PSP的计划表可以让我把时间利用得更好
  • 通过自己一个人做项目也理解到了做项目不仅仅是敲代码,还有设计,思路等重要的工作     

     通过这一次的个人项目,我也了解到了自身的不足,会继续学习充实自我

猜你喜欢

转载自www.cnblogs.com/imenist/p/12533498.html