软件工程:WC项目 Java实现

GitHub项目地址

项目相关要求

基本功能

  • 支持 -c,查看文件的字符数(已实现)
  • 支持 -w,查看文件的单词数(已实现)
  • 支持 -l,查看文件的行数(已实现)

    扩展功能

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

    高级功能

  • 基本的Windows GUI 程序操作(已实现)
  • 支持通过图形界面选取文件(已实现)
  • 支持通过图形界面展现文件的信息(已实现)

解题思路

通过main函数接收参数,然后根据参数调用相应的类方法,按参数中的文件路径读取文件,按行读取文件,使用正则表达式判断文件每一行中的单词数、字符数等信息累加,生成一个新的类来存放读取出来的文件的信息。最后,按要求打印信息。

遇到的困难及解决方法

困难描述:

  • 使用Java的nio读取文件,如果文件包含中文会报错:

java.nio.charset.MalformedInputException: Input length = 1 

  • 使用Java的nio读取文件夹,如果文件夹中还有文件夹,读取会报错

做过哪些尝试:

  • 修改文件读取时的编码方式为GBK:

BufferedReader reader = Files.newBufferedReader(path, Charset.forName("GBK"));

  • 循环判断文件路径,如果是文件夹,拿出其中的文件路径,循环其中的文件夹,直到拿出所有的文件

    public static List

是否解决:

经过以上两种方式,已解决问题。

有何收获:

提高了自己独立编程、思考的能力,自己写的代码,遇到困难会先想是哪里出了问题,如何解决,遇到JDK文档不能解决的,再上网查询资料。通过这次项目,也学习之前没有用过的nio的用法。

关键代码or设计说明

程序设计流程图如下:
流程图
文件读取的功能的实现代码主要在FileUtil类:(以下只显示关键代码)

 //正则表达式用来判断代码行、空行
 public static final Pattern commentLinePattern = Pattern.compile("^//.*$|^/\\*.*$|^\\*.*$|^\\*/.*$");
 public static final Pattern blankLinePattern = Pattern.compile("[{}.,:]{1}");
 public static MyFile singleFile(Path path) throws IOException {
    //MyFile是一个用来带有文件单词数,字符数,行数等属性的对象
    MyFile myFile = new MyFile();
    myFile.setFileName(path.getFileName().toString());
    StringBuilder fileMessage = new StringBuilder();
    //使用BufferReader读取文件
    BufferedReader reader = Files.newBufferedReader(path, Charset.forName(defaultCharsets[0]));
    String line = null;
    int lineNum = 0;
    int charNum = 0;
    int wordNum = 0;
    int commentLine=0;
    int blankLine = 0;
    Matcher matcher = null;
    while((line = reader.readLine())!=null){
        //每读取一行行数加1
        lineNum++;
        String lineTemp = line.trim();
        if(!lineTemp.isEmpty()){
            //按单词的边界分离单词
            String[] words = lineTemp.split("\\W+");
               //这里的spilt方法可能会包含空的元素,要遍历判断后去掉
            for(int i=0;i<words.length;i++){
                if(!words[i].isEmpty()){
                    wordNum ++;
                }
            }
        }
        else{
            //如果为空行,空行数量加1
            blankLine++;
        }
        //去掉空格,即空格不算进字符里面,然后添加这行的字符数
        charNum+=lineTemp.replaceAll(" ","").length();      
        //使用正则表达式匹配注释行
        matcher = commentLinePattern.matcher(lineTemp);
        if(matcher.matches()){commentLine++;}
        //使用正则表达式匹配空行
        matcher =blankLinePattern.matcher(lineTemp);
        if(matcher.matches()){blankLine++;}
        fileMessage.append(line+"\n");
    }
    myFile.setWordNum(wordNum);
    myFile.setCharNum(charNum);
    myFile.setLineNum(lineNum);
    myFile.setBlankLineNum(blankLine);
    myFile.setCommentLineNum(commentLine);
    myFile.setCodeLineNum(lineNum-blankLine-commentLine);
    reader.close();
    myFile.setFileMessage(fileMessage.toString());
    return myFile;
}

WordCalc.java类:根据main中传过来的参数,判断使用的方法:(以下只显示关键代码)

    public void run(){
    try{
        switch(args[0]){
            case "-c":
                charCount(args[1]);
                break;
            case "-w":
                wordCount(args[1]);
                break;
            case "-l":
                lineCount(args[1]);
                break;
            case "-s":
                countForSpecialFileName();
                break;
            case "-a":
                moreMessageCount(args[1]);
                break;
            default:
                error();
        }
    } catch (Exception e){
        error();
        e.printStackTrace();
    }
}

View.java:生成图像界面的类(以下只显示关键代码)

public void actionPerformed(ActionEvent e) {
    //Handle open button action.
    if (e.getSource() == openButton) {
        final JFileChooser fc = new JFileChooser();
        int returnVal = fc.showOpenDialog(this);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            //This is where a real application would open the file.
            try {
                //处理文件的路径,把文件路径中包含的java的特殊字符'\'替换为'\\',然后调用FileUtil类处理文件
               List<MyFile> fileList = FileUtil.readFile(file.getAbsolutePath().replaceAll("\\\\","\\\\\\\\"));
               MyFile f = fileList.get(0);
                //输出文件的信息
               text.append(f.getFileName()+" Message:\n");
               text.append("CharNumber: " + f.getCharNum());
               text.append("  WordNumber: " + f.getWordNum());
               text.append("  LineNumber: " + f.getLineNum());
               text.append("  BlankLineNumber: " + f.getBlankLineNum());
               text.append("  CommentLineNumber: " + f.getCommentLineNum());
               text.append("  CodeLineNumber: "+ f.getCodeLineNum()+newline);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } else {
            text.append("Open command cancelled by user." + newline);
        }
    }

}

测试运行

处理-x参数:

-x
图形界面

处理-a参数:

-a

处理-s参数:

-s

PSP表格

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

项目小结

从这个项目我发现我的Java基础知识掌握的并不好,设计的代码略显冗余,而且代码的可扩展性不高,不过通过本次项目,我遇到问题懂得先自己去官方文档中查找答案,而不是之前去百度找别人的代码。当然,代码测试方面我还做的不够好,仅仅进行了回归测试,对于java类中的方法没有进行单元测试,这是我还需要加强的地方。

猜你喜欢

转载自www.cnblogs.com/guohanghuang/p/9631815.html
今日推荐