個人項目--WC(Java)
阿新 • • 發佈:2018-09-14
模式 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.1 | Personal 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)