个人项目作业

GitHub项目仓库地址:https://github.com/yyffish/WordCount

项目描述

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

 

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

 

具体功能要求:

程序处理用户需求的模式为:

wc.exe [parameter] [file_name]

项目需求

  • 基本功能列表:
  1. wc.exe -c file.c     //返回文件 file.c 的字符数
  2. wc.exe -w file.c    //返回文件 file.c 的词的数目
  3. wc.exe -l file.c      //返回文件 file.c 的行数
  • 扩展功能:
  1.  -s   递归处理目录下符合条件的文件
  2.  -a   返回更复杂的数据(代码行 / 空行 / 注释行)
  • 高级功能:
  1. -x 参数。这个参数单独使用。如果命令行有这个参数,则程序会显示图形界面,用户可以通过界面选取单个文件,程序就会显示文件的字符数、行数等全部统计信息。
  2. 基本的Windows GUI 程序操作
  3. 支持通过图形界面选取文件
  4. 支持通过图形界面展现文件的信息
  • 已实现功能:
  1. -c
  2. -w
  3. -l
  4. -s
  5. -a
  6. -x

PSP

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

 30

 5

· Estimate

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

 30

 5

Development

开发

 620

 615

· Analysis

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

 150

 100

· Design Spec

· 生成设计文档

 45

 5

· Design Review

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

 15

 5

· Coding Standard

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

 20

 5

· Design

· 具体设计

 30

 20

· Coding

· 具体编码

 300

 95

· Code Review

· 代码复审

 30

 350

· Test

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

 30

 35

Reporting

报告

 65

85 

· Test Report

· 测试报告

 30

 70

· Size Measurement

· 计算工作量

 10

 10

· Postmortem & Process Improvement Plan

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

 25

 5

合计

 

 715

705 

解题思路

看完题目,了解到需要统计文件的各种数据,比如字符数,单词数,代码行等等,而且有图形界面就更好。

使用语言:使用JAVA编程,并使用Dynamic Web Project + JSP + JSTL表达式进行开发,并部署到Tomcat服务器中,以实现图形化的功能

设计方案

技术栈

该项目基于Java语言开发,使用JavaWeb配合HTML进行开发。

具体设计

采用Dao-Service-Servlet-JSP四层设计,Dao层做IO逻辑处理,Service层封装Dao层方法,Servlet层做前端数据交互和调用Service层方法,JSP层做数据展示和前端UI界面。

接口文档

fileCountDao层逻辑设计

  1. 根据路径返回FileCount对象 fileCountDao.count
    1. 初始化各个整形变量
    2. 建立IO流
    3. 计算词个数
    4. 封装到FileCount对象中
    5. 返回FileCount对象

folderDao逻辑设计

  1. 根据路径返回Folder对象 folderDao.getFolder
    1. 建立IO流
    2. 将获取的文件封装为fileList和folderList
    3. 将路径和fileList以及folderList封装到Folder对象中
    4. 返回Folder对象

关键代码

Folder对象

 1 package com.wordcount.entity;
 2 
 3 import java.util.List;
 4 
 5 public class Folder {
 6     private List<String> fileList;
 7     private List<String> folderList;
 8     private String path;
 9 
10     public Folder() {
11         super();
12     }
13 
14     public Folder(List<String> fileList, List<String> folderList, String path) {
15         super();
16         this.fileList = fileList;
17         this.folderList = folderList;
18         this.path = path;
19     }
20 
21     public List<String> getFileList() {
22         return fileList;
23     }
24 
25     public void setFileList(List<String> fileList) {
26         this.fileList = fileList;
27     }
28 
29     public List<String> getFolderList() {
30         return folderList;
31     }
32 
33     public void setFolderList(List<String> folderList) {
34         this.folderList = folderList;
35     }
36 
37     public String getPath() {
38         return path;
39     }
40 
41     public void setPath(String path) {
42         this.path = path;
43     }
44 
45 }

FileCount对象

 1 package com.wordcount.entity;
 2 
 3 public class FileCount {
 4     private String fileName;// 文件名
 5     private Integer charNum;// 字符数
 6     private Integer lineNum;// 行数
 7     private Integer wordNum;// 单词数
 8     private Integer codeLineNum;// 代码行
 9     private Integer emptyLineNum;// 空行
10     private Integer remarkLineNUm;// 注释行
11 
12     public FileCount() {
13         super();
14     }
15 
16     public FileCount(String fileName, Integer charNum, Integer lineNum, Integer wordNum, Integer codeLineNum,
17             Integer emptyLineNum, Integer remarkLineNUm) {
18         super();
19         this.fileName = fileName;
20         this.charNum = charNum;
21         this.lineNum = lineNum;
22         this.wordNum = wordNum;
23         this.codeLineNum = codeLineNum;
24         this.emptyLineNum = emptyLineNum;
25         this.remarkLineNUm = remarkLineNUm;
26     }
27 
28     public String getFileName() {
29         return fileName;
30     }
31 
32     public void setFileName(String fileName) {
33         this.fileName = fileName;
34     }
35 
36     public Integer getCharNum() {
37         return charNum;
38     }
39 
40     public void setCharNum(Integer charNum) {
41         this.charNum = charNum;
42     }
43 
44     public Integer getLineNum() {
45         return lineNum;
46     }
47 
48     public void setLineNum(Integer lineNum) {
49         this.lineNum = lineNum;
50     }
51 
52     public Integer getwordNum() {
53         return wordNum;
54     }
55 
56     public void setwordNum(Integer wordNum) {
57         this.wordNum = wordNum;
58     }
59 
60     public Integer getCodeLineNum() {
61         return codeLineNum;
62     }
63 
64     public void setCodeLineNum(Integer codeLineNum) {
65         this.codeLineNum = codeLineNum;
66     }
67 
68     public Integer getEmptyLineNum() {
69         return emptyLineNum;
70     }
71 
72     public void setEmptyLineNum(Integer emptyLineNum) {
73         this.emptyLineNum = emptyLineNum;
74     }
75 
76     public Integer getRemarkLineNUm() {
77         return remarkLineNUm;
78     }
79 
80     public void setRemarkLineNUm(Integer remarkLineNUm) {
81         this.remarkLineNUm = remarkLineNUm;
82     }
83 
84 }

FolderDao.java

 1 package com.workcount.dao;
 2 
 3 import java.io.File;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import com.wordcount.entity.Folder;
 8 
 9 public class FolderDao {
10 
11     /**
12      * 根据路径返回Folder对象
13      * 
14      * @param path
15      * @return
16      */
17     public Folder getFolder(String path) {
18         Folder folder = new Folder();
19         File dir = new File(path);
20         String[] tempList = dir.list();
21         List<String> fileList = new ArrayList<>();
22         List<String> folderList = new ArrayList<>();
23         for (int i = 0; i < tempList.length; i++) {
24             String tempPath = path + tempList[i] + "/";
25             File tempFile = new File(tempPath);
26             if (tempFile.isFile()) {
27                 if (tempList[i].contains(".txt")) {
28                     fileList.add(tempList[i]);
29                 }
30             } else {
31                 folderList.add(tempList[i]);
32             }
33         }
34         folder.setFileList(fileList);
35         folder.setPath(path);
36         folder.setFolderList(folderList);
37         return folder;
38     }
39 }

FileCountDao.java

package com.workcount.dao;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.wordcount.entity.FileCount;

public class FileCountDao {

    /**
     * 根据路径返回FileCount对象
     * 
     * @param path
     * @return
     */
    public FileCount count(String path) {
        FileCount fileCount = new FileCount();
        String regxNodeBegin = "\s*/\*.*";
        String regxNodeEnd = ".*\*/\s*";
        String regx = "//.*";
        String regxSpace = "\s*";
        boolean flagNode = false;
        int lineNum = 0;
        int wordNum = 0;
        int charNum = 0;
        int codeLineNum = 0;
        int emptyLineNum = 0;
        int remarkLineNUm = 0;
        try {
            StringBuffer stringBuffer = new StringBuffer();
            // 创建类进行文件的读取,并指定编码格式为utf-8
            InputStreamReader read = new InputStreamReader(new FileInputStream(path), "utf-8");
            // 可用于读取指定文件
            BufferedReader in = new BufferedReader(read);
            // 定义一个字符串类型变量str
            String str = null;
            while ((str = in.readLine()) != null) {// readLine()方法, 用于读取一行,只要读取内容不为空就一直执行
                lineNum++;// 每循环一次就进行一次自增,用于统计文本行数
                charNum += str.length();// 用于统计总字符数
                stringBuffer.append(str + '
');
                if (str.matches(regxNodeBegin) && str.matches(regxNodeEnd)) {
                    ++remarkLineNUm;
                    continue;
                }
                if (str.matches(regxNodeBegin)) {
                    ++remarkLineNUm;
                    flagNode = true;
                } else if (str.matches(regxNodeEnd)) {
                    ++remarkLineNUm;
                    flagNode = false;
                } else if (str.matches(regxSpace))
                    ++emptyLineNum;
                else if (str.matches(regx))
                    ++remarkLineNUm;
                else if (flagNode)
                    ++remarkLineNUm;
                else
                    ++codeLineNum;
            }
            in.close();// 关闭流
            Pattern pattern = Pattern.compile("\b[a-zA-Z]+\b");
            Matcher matcher = pattern.matcher(stringBuffer.toString());
            while (matcher.find()) {
                wordNum++;
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        fileCount.setwordNum(wordNum);
        fileCount.setLineNum(lineNum);
        fileCount.setCharNum(charNum);
        fileCount.setCodeLineNum(codeLineNum);
        fileCount.setEmptyLineNum(emptyLineNum);
        fileCount.setRemarkLineNUm(remarkLineNUm);
        fileCount.setFileName(path.substring(path.lastIndexOf("/") + 1));
        return fileCount;
    }
}

CountServlet.java

 1 package com.workcount.servlet;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 import com.wordcount.entity.FileCount;
12 import com.workcount.service.FileCountService;
13 
14 /**
15  * Servlet implementation class CountServlet
16  */
17 @WebServlet("/count")
18 public class CountServlet extends HttpServlet {
19     private static final long serialVersionUID = 1L;
20 
21     /**
22      * @see HttpServlet#HttpServlet()
23      */
24     public CountServlet() {
25         super();
26         // TODO Auto-generated constructor stub
27     }
28 
29     /**
30      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
31      *      response)
32      */
33     protected void doGet(HttpServletRequest request, HttpServletResponse response)
34             throws ServletException, IOException {
35         FileCountService fileCountService = new FileCountService();
36         FileCount fileCount = null;
37         String path = request.getParameter("path");
38         if (path != null) {
39             fileCount = fileCountService.count(path);
40         } else {
41             fileCount = new FileCount();
42         }
43         request.setAttribute("fileCount", fileCount);
44         request.getRequestDispatcher("count.jsp").forward(request, response);
45     }
46 
47     /**
48      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
49      *      response)
50      */
51     protected void doPost(HttpServletRequest request, HttpServletResponse response)
52             throws ServletException, IOException {
53         // TODO Auto-generated method stub
54         doGet(request, response);
55     }
56 
57 }

MainServlet.java

 1 package com.workcount.servlet;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 import com.wordcount.entity.Folder;
12 import com.workcount.service.FolderService;
13 
14 /**
15  * Servlet implementation class TestServlet
16  */
17 @WebServlet("/main")
18 public class MainServlet extends HttpServlet {
19     private static final long serialVersionUID = 1L;
20 
21     /**
22      * @see HttpServlet#HttpServlet()
23      */
24     public MainServlet() {
25         super();
26         // TODO Auto-generated constructor stub
27     }
28 
29     /**
30      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
31      *      response)
32      */
33     protected void doGet(HttpServletRequest request, HttpServletResponse response)
34             throws ServletException, IOException {
35         // TODO Auto-generated method stub
36         doPost(request, response);
37     }
38 
39     /**
40      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
41      *      response)
42      */
43     protected void doPost(HttpServletRequest request, HttpServletResponse response)
44             throws ServletException, IOException {
45         // TODO Auto-generated method stub
46         FolderService folderService = new FolderService();
47         Folder folder = new Folder();
48         String path = "C:/";
49         if (request.getParameter("path") != null) {
50             path = request.getParameter("path") + "/";
51         }
52         folder = folderService.getFolder(path);
53         request.setAttribute("folder", folder);
54         request.getRequestDispatcher("/table.jsp").forward(request, response);
55     }
56 
57 }

运行测试

  • 将WordCount项目部署到Tomcat中

  • 网页首页:向本地8080端口的WordCount项目发送main请求,即可得到本机C盘的文件路径

  • 打开2345Downloads文件夹,可以查看到txt文件。

  • 点击11.txt文件即可查询相关信息,其中文本如下

   

        

项目总结

对于我个人来说,开发经验不足,本来是想用spring boot进行开发的,但是对spring boot使用经验不够对,有很多问题无法解决,因此选择用JavaWeb进行开发,对于其他同学,开发时间还是比较长的,遇到的问题主要还是通过百度解决,主要话费的时间在前端上,后端代码还是比较简单的。

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/yuyifeng/p/12499466.html