項目地址:https://gitee.com/yangfj/wordcount_projecthtml
1.軟件需求分析:java
撰寫PSP表格:git
PSP2.1數組 |
PSP階段安全 |
預估耗時函數 (分鐘)工具 |
實際耗時單元測試 (分鐘)學習 |
Planning測試 |
計劃 |
20 |
15 |
· Estimate |
· 估計這個任務須要多少時間 |
20 |
15 |
Development |
開發 |
960 |
880 |
· Analysis |
· 需求分析 (包括學習新技術) |
10 |
20 |
· Design Spec |
· 生成設計文檔 |
40 |
20 |
· Design Review |
· 設計複審 (和同事審覈設計文檔) |
10 |
30 |
· Coding Standard |
· 代碼規範 (爲目前的開發制定合適的規範) |
50 |
10 |
· Design |
· 具體設計 |
50 |
20 |
· Coding |
· 具體編碼 |
500 |
650 |
· Code Review |
· 代碼複審 |
100 |
30 |
· Test |
· 測試(自我測試,修改代碼,提交修改) |
200 |
50 |
Reporting |
報告 |
150 |
100 |
· Test Report |
· 測試報告 |
80 |
50 |
· Size Measurement |
· 計算工做量 |
20 |
20 |
· Postmortem & Process Improvement Plan |
· 過後總結, 並提出過程改進計劃 |
50 |
30 |
|
合計 |
1130 |
995 |
結果分析,在完成編碼撰寫博客的時候,確實發現了許多計劃與實際出入的地方,好比說代碼規範,在實際編碼的時候,根本沒有考慮到這一點,只是在最終編寫完成以後才意識到,因而最後纔開始改編碼規範,寫次開發的時候就應該提早考慮,雖然只是一我的在開發。還有就是整體來講並非很完整的進行了測試,只是有一些單元測試,之後會多瞭解一下代碼測試這一塊的技能。
2.解題思路
由於之前用到的代碼管理工具都是SVN,尚未用過Git ,只是偶爾在GitHub上面逛逛,因此首先想的是成功安裝Git,而且實現代碼管理,而後就找了很久的資料,包括Git如何提交到碼雲等等,詳見個人另外一篇博文:
https://www.cnblogs.com/shoneworn/p/8251556.html
而後看了看題目,發現應該先肯定用什麼語言代碼來實現,雖然本身擅長C#,也學過Python,但仍是決定用java語言比較好,一個是由於本身如今正在學習java,正好能夠經過這個項目提高本身,主要採用的技術是java IO流方面的技術。
1.對於常見的java項目,應該利用什麼才能實如今命令行中進行輸入輸出的信息讀取?
2.如何判斷控制檯是要求的統計字符數,單詞數,總行數,存入特定文件的相應基礎功能?
3.如何在支持基礎功能的基礎上,拓展其待實現的功能而又能與原代碼區分開來?
3.需求分析
具體的需求其實大體能夠總結爲一下幾點:
1.輸入:
輸入指定的文件,採用程序統計文件的字符數、單詞數、行數、
2.輸出:
輸出文件(以指定的格式)
3.拓展:
支持 返回高級選項(代碼行 空行 註釋行)
遞歸處理符合條件的文件,考慮程序的時間複雜度和空間複雜度
4.程序實現過程
項目一共兩個文件,一個爲主函數,一個爲實現具體功能類。
mian函數:
public class WorkCount { public static void main(String[] args) throws Exception { // 統計一個文件的字符數,單詞數,行數 Scanner input = new Scanner(System.in); System.out.println("please input path:"); String path = input.next(); int countChar = 0; int countword = 0; int countline = 0; InputStreamReader isr = new InputStreamReader(new FileInputStream(path)); //InputStreamReader將字符流向字節流轉換。 //InputStreamReader isr = new InputStreamReader(new FileInputStream(絕對文件名)); //用來讀取文件中的數據 BufferedReader br = new BufferedReader(isr);//使用緩衝區,可使用緩衝區的read(),readLine()方法; while(br.read()!=-1)//read()=-1表明數據讀取完畢 { String s = br.readLine(); countChar += s.length();//字符個數就是字符長度 countword += s.split(" ").length;//split() 方法用於把一個字符串分割成字符串數組,字符串數組的長度,就是單詞個數 countline++;//由於是按行讀取,因此每次增長一便可計算出行的數目 } isr.close();//關閉文件 System.out.println("char cont "+countChar); System.out.println("word count "+countword ); System.out.println("line count "+countline); } }
實現具體功能類:
返回字符的個數
int CharCount(String s)//用來輸入文件並返回字符的個數 { int count = 0; Pattern p = Pattern.compile("[a-zA-Z]"); Matcher m = p.matcher(str); while(m.find()){ count++; } return count; }
}
返回單詞出現總數 :
public static int countdanci(String[] args) { //逐行讀文件 BufferedReaderbr = null; try { Map<String,Integer>map = newHashMap<String,Integer>(); br = new BufferedReader(new FileReader("d:/mywords.txt")); Stringline; while(null != (line = br.readLine())){ System.out.println(line); //將字符串用空格分隔 String[]ss = line.split("\\s+"); for(String s : ss){ if(map.containsKey(s)){ map.put(s, map.get(s)+1); }else{ map.put(s, 1); } } } Set<String>keys = map.keySet(); for(String key : keys){ System.out.println(key + "有:" + map.get(key) + "個."); } }catch(FileNotFoundException e) { e.printStackTrace(); }catch(IOException e) { e.printStackTrace(); }finally { if(null != br){ try { br.close(); }catch(IOException e) { e.printStackTrace(); } } }
文件總行數:
public static HangCount(String[] args) { try{ File file =new File("c:\\test.txt"); if(file.exists()){ FileReader fr = new FileReader(file); LineNumberReader lnr = new LineNumberReader(fr); int linenumber = 0; while (lnr.readLine() != null){ linenumber++; } System.out.println("Total number of lines : " + linenumber); lnr.close(); }else{ System.out.println("File does not exists!"); } }catch(IOException e){ e.printStackTrace(); } }
文件空白行數,註釋行數
public static void CountLine(File f) throws FileNotFoundException, IOException{ //經過調用一個以前定義的對象來表示此文件鏈接,file參數表示的路徑做爲參數調用javaLine方法 String strLine = "";//建立了一個對象。而且加入字符串池中 String str = fromFile(f); //str爲引用 "" 是 引用指向的的值,定義一個String 類型的變量str,併爲其賦值 if (str.length() > 0) { while (str.indexOf('\n') != -1) { //經過一個wile循環體判斷這個值,從而作到字符串處理,使得字符串以正確方式顯示 totle++; strLine = str.substring(0, str.indexOf('\n')).trim(); if (strLine.length() == 0 ) { blank++; }else if (strLine.charAt(0) == '*' || strLine.charAt(0) == '/') { comments++; }else{ source++; String regEx = "^*//"; if(regEx(strLine,regEx)){ comments++; } } str = str.substring(str.indexOf('\n') + 1, str.length()); //返回給定區間的字符串,以上通過轉換後,str可以正常顯示 } } }
輸出到文件:
public void outPutfile(String infilename,String outfiename) { try { fileReader(infilename); File file=new File(outfiename); if(!file.exists()) { file.createNewFile(); } String lineSents=""; String wordSents=" "; String charSents=" "; String charCon=CharCount/callCounter+""; String lineCon=LineCount/callCounter+""; String wordCon=WordCount/callCounter+""; charSents=charSents.concat(charCon).concat("\r\n");//使用concat()方法連接兩個字符串 lineSents=lineSents.concat(lineCon).concat("\r\n"); wordSents=wordSents.concat(wordCon).concat("\r\n"); FileWriter fw=new FileWriter(file.getAbsoluteFile()); BufferedWriter bWriter=new BufferedWriter(fw); bWriter.write(charSents);//寫入到文件 bWriter.write(lineSents); bWriter.write(wordSents); bWriter.close();//必須關閉才能寫入文件,不然寫入無效 fw.close(); if(file.length()!=0) System.out.println("write file succeed..."); else System.out.println("write file failed..."); } catch (IOException e) {//跑出異常 // TODO Auto-generated catch block e.printStackTrace(); } }
5.測試過程:
wc.exe -c file.c //返回文件 file.c 的字符數
wc.exe -w file.c //返回文件 file.c 的單詞總數
wc.exe -l file.c //返回文件 file.c 的總行數
wc.exe -o outputFile.txt //將結果輸出到指定文件outputFile.txt
......
6.測試結果:
wc.exe -c C:\Learning\Java\code\temp\src\com\hcedu\dao\LoginDao.java
wc.exe -w C:\Learning\Java\code\temp\src\com\hcedu\dao\LoginDao.java
wc.exe -l C:\Learning\Java\code\temp\src\com\hcedu\dao\LoginDao.java
wc.exe -c C:\Learning\Java\code\temp\src\com\hcedu\dao\LoginDao.java
wc.exe -m C:\Learning\Java\code\temp\src\com\hcedu\dao\LoginDao.java
7.總結
此次的WorkCount做業,實際上是一個較爲完整的項目,其中包括了需求分析、系統設計、編碼實現、測試分析等等。之前寫代碼並無寫過如此完整的代碼流程,其中不少時候都沒有寫過文檔和測試分析,經過此次的編碼,我意識到了代碼的安全性,程序的健壯性。規範的代碼更對以後的測試分析有利。同時更要考慮到用戶的感覺,讓代碼變的更加人性化才行。
最後,其實此次的代碼我還存在着許多的不足,我最開始拿到這個項目,寫完需求分析以後就沒有動過博客,後面逐一實現代碼以後又對博客進行的刪減去,總的來講,仍是一直都在寫代碼,而忽視了文檔的重要性,在之後的編碼過程當中,更應該增強對文檔的投入。
8.參考文獻
鄒欣老師在《構建之法》中設計的第一項我的做業:http://www.cnblogs.com/xinz/p/7426280.html