1. 程式人生 > >個人項目--WC(Java)

個人項目--WC(Java)

模式 nbsp man 合計 dir 同時 發的 開發 結構

Github地址: https://github.com/lllm-li/lllm

項目相關要求

實現一個統計程序,它能正確統計程序文件中的字符數、單詞數、行數,以及還具備其他擴展功能,並能夠快速地處理多個文件。
具體功能要求:

基本功能列表:

wc.exe -c file.c //返回文件 file.c 的字符數(實現)

wc.exe -w file.c //返回文件 file.c 的詞的數目 (實現)

wc.exe -l file.c //返回文件 file.c 的行數(實現)

擴展功能:
wc.exe -s 遞歸處理目錄下符合條件的文件。(實現)
wc.exe -a 返回更復雜的數據(代碼行 / 空行 / 註釋行)。(實現)

PSP

PSP2.1Personal Software Process Stages預估耗時(分鐘)實際耗時(分鐘)
Planning 計劃 30 40
· Estimate · 估計這個任務需要多少時間 40 60
Development 開發 900 1200
· Analysis · 需求分析 (包括學習新技術) 180 150
· Design Spec · 生成設計文檔 40 60
· Design Review · 設計復審 (和同事審核設計文檔) 40 60
· Coding Standard · 代碼規範 (為目前的開發制定合適的規範) 20 60
· Design · 具體設計 80 120
· Coding · 具體編碼 600 1000
· Code Review · 代碼復審 30 20
· Test · 測試(自我測試,修改代碼,提交修改) 120 60
Reporting 報告 120 240
· Test Report · 測試報告 30 30
· Size Measurement · 計算工作量 10 20
· Postmortem & Process Improvement Plan · 事後總結, 並提出過程改進計劃 60 30
合計 2300 3150

解題思路

看清項目的需求,設計流程框架,結合開發語言寫出實現函數所用的方法,通過查閱資料開始編寫代碼,檢測代碼,修改代碼。

設計的實現

代碼分為三大部分:測試類wc,管理類wcManage,功能實現類wildCard、blankLine等

關系結構如下圖所示

技術分享圖片

代碼說明

wc主類的測試

public static void main(String args[]) throws IOException {
        
        wcManage wcmanage=new wcManage();
        File f1=new File(args[1]);
        String s=f1.getName();
         
        wildCard fs=new wildCard();
        File fk[]=fs.getFiles(f1.getParent(), s);
           for(File f:fk) {
               wcmanage.setFileDirectory(f.getAbsolutePath());
               if(args[0].equals("-l")) {
                   System.out.println(f);
                   wcmanage.rowNumPrint();
               }
               if(args[0].equals("-w")) {
                   System.out.println(f);
                   wcmanage.wordNumPrint();
               }
               if(args[0].equals("-c")) {
                   System.out.println(f);
                   wcmanage.characterNumPrint();
               }
               if(args[0].equals("-a")) {
                   System.out.println(f);
                   wcmanage.blankLinePrint();
                   wcmanage.codeLinePrint();
                   wcmanage.commentLinePrint();
                }
           }
        if(args[0].equals("-s"))wcmanage.recursivePrint();
    }    

wcManage類管理方法

String fileDirectory;
    
    void rowNumPrint(){
        rowNum rn=new rowNum();
        rn.setFileDirectory(fileDirectory);
        rn.rowNum();
        System.out.println("行數:"+rn.rownum);
    }
    
    void wordNumPrint(){
        wordNum wn=new wordNum();
        wn.setFileDirectory(fileDirectory);
        wn.wordNum();
        System.out.println("詞數:"+wn.wordnum);
    }
    
    void characterNumPrint(){
        characterNum cn=new characterNum();
        cn.setFileDirectory(fileDirectory);
        cn.characterNum();
        System.out.println("字符數:"+cn.characternum);
    }
    
    void blankLinePrint() {
        blankLine bl=new blankLine();
        bl.setFileDirectory(fileDirectory);
        bl.blankLine();
        System.out.println("空行數:"+bl.blankline);
    }
    
    void codeLinePrint() {
        codeLine cl=new codeLine();
        cl.setFileDirectory(fileDirectory);
        cl.codeLine();
        System.out.println("代碼行:"+cl.codeline);
    }
    
    void commentLinePrint() {
        commentLine cl=new commentLine();
        cl.setFileDirectory(fileDirectory);
        cl.commentLine();
        System.out.println("註釋行:"+cl.commentline);
    }
    
    void recursivePrint() {
        Recursive r=new Recursive();
        r.setFileDirectory(fileDirectory);
        System.out.println("所查詢匹配的文件:");
        r.Recursive();
    }
    
    void setFileDirectory(String fileDirectory) {
        this.fileDirectory=fileDirectory;
    }

空行數

public void blankLine(){//讀取空行數
        try {
            String s;
            String s1[];
            Pattern p=Pattern.compile(REGEX);
            BufferedReader br=new BufferedReader(new FileReader(fileDirectory));
            while((s=br.readLine())!=null) {
                if(s.matches("[\\s]*")) blankline++;
                else {
                    s1=p.split(s.trim());
                    if(s1[0].length()==1&&s1.length==1)blankline++;
                }
            }
            br.close();
        }catch(Exception e) {
            
        }
    }

字符數

public void characterNum(){//讀取字符數
        try {
            String s;
            String s1[];
            Pattern p=Pattern.compile(REGEX);
            BufferedReader br=new BufferedReader(new FileReader(fileDirectory));
            while((s=br.readLine())!=null) {
                if(s.matches("[\\s]*")) continue;
                else {
                    s1=s.split(REGEX);
                    for(int i=0;i<s1.length;i++)characternum+=s1[i].length();
                }
            }
            br.close();
        }catch(Exception e) {
            
        }
    }

代碼行

public void codeLine() {//讀取代碼行
        try {
            String s;
            String s1[];
            Pattern p=Pattern.compile(REGEX);
            BufferedReader br=new BufferedReader(new FileReader(fileDirectory));
            while((s=br.readLine())!=null) {
                if(s.matches("[\\s]*")) continue; 
                else {
                    s1=p.split(s.trim());
                    if(s1.length>1||s1[0].length()>1)codeline++;
                }
            }
            br.close();
            
            commentLine cl=new commentLine();
            cl.setFileDirectory(fileDirectory);
            cl.commentLine();
            
            codeline-=cl.commentline;
            
        }catch(Exception e) {
            
        }
    }

註釋行

public void commentLine() {//讀取註釋行
        try {
            String s;
            int i=0,j=0;
            BufferedReader br=new BufferedReader(new FileReader(fileDirectory));
            while((s=br.readLine())!=null) {
                 i++;
                 if(s.indexOf("//")!=-1)commentline++;
                 if(s.indexOf("/*")!=-1) j=i;
                 if(s.indexOf("*/")!=-1) commentline+=i-j+1;
            }
            br.close();
        }catch(Exception e) {
            
        }
    }

遞歸處理

public void Recursive() {//讀取目錄下的文件
        File file=new File(fileDirectory);
        file=new File(file.getParent());
        fs=file.listFiles();
        for(File f:fs) {
            if(!f.isDirectory()) {
                System.out.println("  "+f);
            };
        }
    }

行數

public void rowNum(){//讀取行數
        try {
            String s;
            BufferedReader br=new BufferedReader(new FileReader(fileDirectory));
            while((s=br.readLine())!=null) {
                rownum++;
            }
            br.close();
        }catch(Exception e) {
            
        }
    }

通配符

public static File[] getFiles(String filepath,String filename) {
         File file = new File(filepath);
         filename=filename.replace("*", ".*");
         filename=filename.replace("?", ".?");
         Pattern p = Pattern.compile(filename);
         ArrayList<File> list = filePattern(file, p);
         File f[]= new File[list.size()];
         return list.toArray(f);
       }
    
    private static ArrayList<File> filePattern(File file, Pattern p) {  
        if (file.isFile()) {
               Matcher matcher= p.matcher(file.getName());
               if (matcher.matches()) {
                 ArrayList<File> list = new ArrayList<File>();
                 list.add(file);
                 return list;
               }
             }
             else if (file.isDirectory()) {
               File[] files = file.listFiles();
               if (files!=null && files.length>0) {
                 ArrayList<File> list = new ArrayList<File>();
                 for (int i = 0; i < files.length; i++) {
                   ArrayList<File> rlist =filePattern(files[i], p);
                   if (rlist != null) {
                     list.addAll(rlist);
                   }
                 }
                 return list;
               }
             }
             return null;
    }

詞數

public void wordNum(){//讀取詞的數目
        try {
            String s;
            Pattern p=Pattern.compile(REGEX);
            BufferedReader br=new BufferedReader(new FileReader(fileDirectory));
            while((s=br.readLine())!=null) {
                if(s.matches("[\\s]*"))continue;
                 wordnum+=p.split(s).length;
            }
            br.close();
        }catch(Exception e) {
            
        }
    }

測試文件

技術分享圖片

測試結果:

技術分享圖片

遇到的困難:

通配符模式的實現,無法得到所寫字符串變成正則表達式。

解決辦法:

通過查詢資料得到 Pattern p=Pattern.compile(REGEX);即可將所要字符串變成正則表達式

總結:

結構清晰,但是代碼冗余量較大,實現基本功能和擴展功能。同時也學會了github上傳的方法。測試代碼要具有代表性,否則會導致漏掉細節而導致功能出錯,同時也復習了正則表達式,了解了項目開發的基本流程,收獲還是很大的。

改進原代碼可以把基本功能和擴展功能一並寫到一個類,這樣可以減少代碼的冗余量。

個人項目--WC(Java)