第一次作業:Word Count


1. 項目需求說明

剛拿到題目時,我先看了題目需求,並列出主要要實現的功能:
1. 讀取文件內容
2. 計算字符數
3. 計算單詞數
4. 計算行數
5. 向文件寫入內容
經過主要的功能分析后,我決定用我比較熟悉的java語言來完成這個題目。

舉例:

wc.exe –c file.c,則輸出結果保存在result.txt中,內容格式如下(注意大小寫):
file.c, 字符數: 50

wc.exe –w file.c,則輸出結果保存在result.txt中,內容格式如下(注意大小寫):
file.c, 單詞數: 30

wc.exe –l file.c,則輸出結果保存在result.txt中,內容格式如下(注意大小寫):
file.c, 行數: 10

wc.exe –l –c file.c,則統計file.c中的字符數和行數,輸出結果保存在result.txt中,內容格式如下:
file.c, 字符數: 50
file.c, 行數: 10

2. 編碼過程

  • PSP表格
**PSP2.1 ** PSP階段 預估耗時(分鍾) 實際耗時(分鍾)
Planning 計划 10 1
· Estimate · 估計這個任務需要多少時間 10 1
Development 開發 170 535
· Analysis · 需求分析 (包括學習新技術) 10 5
· Design Spec · 生成設計文檔 30 40
· Design Review · 設計復審 (和同事審核設計文檔) 10 0
· Coding · 代碼規范 (為目前的開發制定合適的規范) 10 0
· Code Review · 具體設計 10 5
· Test · 具體編碼 60 410
Reporting · 代碼復審 10 5
· Test Report 報告 30 40
· Size Measurement · 測試報告 30 10
· Postmortem & Process · 計算工作量 5 10
Improvement Plan · 事后總結, 並提出過程改進計划 10 120
合計 210 650
  • 小總結:

本次計划時間和實際花費的時間有很大的差異,從表格中可以分析出,
我在自己評估自己在具體編碼的時間太樂觀,這個項目看起來需求簡單,
但由於我單java的字符IO流把握不是很熟悉,我也在使用正則表達式的
時候,出現了問題,導致在調試過程中花費了很多的時間。
其他也有出現偏差的地方,如:估計這個任務需要多少時間,
代碼規范, 事后總結, 並提出過程改進計划等。由於我第一次通過
規范的軟件設計過程的方法完成這次作業,對該過程缺少實踐,所以
不能對時間把握的很好,希望能夠在下一次做得更好。

2. 1 解題思路

我分析了用java語言完成該題目主要需要運用的知識是:文件的IO流部分的知識。
於是我復習了我自己學習java IO字符流模塊的知識和筆記,相關筆記如下:


/*
------------|   Reader    抽象類    輸入字符流的基類
-----------------------|   FileReader    讀取文件的輸入字符流

FileReader的步驟:

	1. 找到目標文件
	2. 建立數據輸入字符流通道
	3. 讀取數據

*/
public class Demo1 {
       public static void main(String[] args) throws IOException {
             read1();
             read2();
       }
       public static void read1() throws IOException {
             File file = new File("E:/作業/Java/文件/b.txt");
             FileReader fileReader = new FileReader(file);
             int content = 0;
             while((content = fileReader.read()) != -1){//每次讀一個字符
                    System.out.print((char)content);
             }
             fileReader.close();
       }
       public static void read2() throws IOException {
             File file = new File("E:/作業/Java/文件/b.txt");
             FileReader fileReader = new FileReader(file);
             //建立緩沖字符數組
             char[] buf = new char[1024];
             int length = 0;
             while((length = fileReader.read(buf)) != -1)
             {
                    System.out.println(new String(buf, 0, length));
             }
       }
}



/*
--------------|    Write    抽象類    輸出字符流的基類
--------------------------|    FileWriter    向文件數據輸出數據的輸出字符流

FileWriter 的使用步驟:

	1. 找到目標文件
	2. 建立字符輸出流通道
	3. 輸出數據
	4. 關閉文件

注意:

	1. filewriter底層維護了一個1024的字符數組,寫的數據先存在該數組中,當調用flush或close方法或填滿了數組才會保存到硬盤上。
	2. new FileWriter(file);    如果目標文件不存在,會自動創建。
	3. new FileWriter(file);默認先清空數據。如果要直接添加數據,使用FileWriter(File,true)。

*/
public class Demo2 {
       public static void main(String[] args) throws IOException {
             write();
       }
       public static void write() throws IOException {
             File file = new File("E:/作業/Java/文件/b.txt");
             FileWriter fileWriter = new FileWriter(file);
             String data = "今天很開心";
             fileWriter.write(data);
             fileWriter.close();
       }
}

然后,我又思考發現,在計算單詞數的時候,可以通過正則表達式來截取字符串的方式計算單詞數量,
所有我又復習了正則表達式的相關用法,相關示例如下:

	范圍詞

            [abc]          出現的只能是abc其中的一個
            [^abc]         出現的只能是除了abc 的一個任意字符
            [a-z1-9&$] 出現的只能是兩頭字母包括在內的字符(即:a~z  或1~9 或&或$)

2. 2 程序設計實現過程

在實際編碼中,我使用了四個類,其類名和相關用途如下:
BaseCount:解析用戶輸入的命令行、調用JudgeOption類
相關方法:
wordCountMain()

BaseFunc:實現計算字符數、單詞書、行數這三個方法
相關方法:
count_charsNum(String path)
count_wordsNum(String path)
count_linesNum(String path)

JudgeOption:判斷用戶輸入參數,調用BaseFunc中對應的相關方法
相關方法:
judge(String arg, String readPath, String writePath)

WriteCount:把計算后的結果寫出到指定文件
相關方法:
writeCount(String str, String path)
initFile(String path):如果寫出的文件存在,將文件內容清空

2. 3 代碼說明

BaseFunc 類


public class BaseFunc {
        //計算字符數
	public static int count_charsNum(String path){
		int count = 0;
		try {
			FileReader fileReader = new FileReader(path);
			char[] buf = new char[1024];
			int length = 0;
			while( (length = fileReader.read(buf)) != -1){
				count += length;
			}
			fileReader.close();
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return count;
	}
	//計算單詞數
	public static int count_wordsNum(String path) {
		int count = 0;
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
			  while(br.read()!=-1) 
			  {
			   String s = br.readLine();
			   
			   for(int i=0; i<s.split("[^a-zA-Z]").length; i++){//通過非英文字符對字符串進行截取
				   
				   if( !s.split("[^a-zA-Z]")[i].isEmpty()){//去掉兩個連續非英文字符 所截取的空字符串
					   count ++;
				   }
			   }
			   
			   
			  }
			  br.close(); 
		}  catch (Exception e) {
			System.out.println(e);
		}
		
		
		return count;
		
	}
        //計算行數
	public static int count_linesNum(String path) {
		int count = 0;
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
			while(br.read()!=-1) 
			{
				String s = br.readLine();//每次讀取一行,行數加一
				
				count++;
			}
			br.close(); 
		}  catch (Exception e) {
			System.out.println(e);
		}
		
		
		return count;
		
	}
}


JudgeOption 類



public class JudgeOption {
        //判斷用戶輸入的參數,調用相關方法
	public static void judge(String arg, String readPath, String writePath) {
		int count = 0;
		String str = "";
		
		switch (arg) {
		case "-c":
		case "—c":
			count = BaseFunc.count_charsNum(readPath);
			str = readPath.split("/")[ (readPath.split("/").length-1) ];
			str += ", 字符數:";
			str += count;
			WriteCount.writeCount(str, writePath);
			break;
			
		case "-w":
		case "—w":
			count = BaseFunc.count_wordsNum(readPath);
			str = readPath.split("/")[ (readPath.split("/").length-1) ];
			str += ", 單詞數:";
			str += count;
			WriteCount.writeCount(str, writePath);
			break;
			
		case "-l":
		case "—l":
			count = BaseFunc.count_linesNum(readPath);
			str = readPath.split("/")[ (readPath.split("/").length-1) ];
			str += ", 行數:";
			str += count;
			WriteCount.writeCount(str, writePath);
			break;
			
		}
	}
}


2. 4 測試設計過程

我總共設計了10個測試用例,其中7個為用戶輸入命令測試,3個為文件內容測試。

  • 設計思路

對於用戶輸入命令的測試:由於我的主函數中有一行代碼,即:用來調用我所有的項目方法,沒有功能代碼,因此可以確保其正確性。
其他所有函數中,若出現錯誤均將錯誤拋出,我使用MTest類來實現測試方法,當主程序中有異常拋出時,則捕捉並進行處理,即:輸出異常,終止程序。
並添加代碼:把預期結果用字符串數組保存,用if語句與實際結果判斷,如果不符合,就assert(判斷)

對於文件內容的測試,則需要手動將文件內容進行修改。

輸入命令測試

  • wc.exe -c f.c
    輸出結果:

  • wc.exe -w f.c
    輸出結果:

  • wc.exe -l f.c
    輸出結果:

  • wc.exe -c -w -l f.c
    輸出結果:

  • wc.exe -s f.c
    輸出結果:

  • wc.exe
    輸出結果:

  • wc.exe -w f.txt
    輸出結果:

其中,f.c的內容如下:


count = BaseFunc.count_charsNum(readPath);
			str = readPath.split("/")[ (readPath.split("/").length-1) ];
			str += ", 字符數:";
			str += count;
			WriteCount.writeCount(str, writePath);
			break;

文件內容測試

  • 文件為空
    結果:

  • 文件1

aaaaaaaaa

結果:

  • 文件2
public static void main(String[] args) {
		String[] options = "-c -w -l src/file.c".split(" ");
//		System.out.println(options.length);
		
		/*for(int i=0; i<options.length; i++){
			System.out.println(options[i]);
		}*/
//		wordCountMain(options);
		
		
		wordCountMain(args);
}

結果:

其中,輸入命令為:
wc.exe -c -w -l f.c

  • - 測試代碼如下:.
//該代碼為判斷程序是否出錯的測試,而判斷輸出結果是否正確的測試代碼這里不給出
public class MTest {
	public void mtest(){
		try {
			ArrayList<String[]> list = new ArrayList<String[]>();
			String[] options1 = "-c f.c".split(" ");
			String[] options2 = "-w f.c".split(" ");
			String[] options3 = "-l f.c".split(" ");
			String[] options4 = "-c -w -l f.c".split(" ");
			String[] options5 = "-s f.c".split(" ");
			String[] options6 = " ".split(" ");
			String[] options7 = "-w f.txt".split(" ");
			list.add(options1);
			list.add(options2);
			list.add(options3);
			list.add(options4);
			list.add(options5);
			list.add(options6);
			list.add(options7);
			
			for(int i=0; i<7; i++){
				BaseCount.wordCountMain(list.get(i));
			}
			
		} catch (Exception e) {
			System.out.println(e);
			assert(false);
		}
		
	}
}

3. 總結反思:


   通過這次完成WordCount作業的過程,我學到了很多:
1. 如何使用git對我的項目進行管理。
2. 如何使用博客,並寫一篇自己的博文。
3. 復習、加深了對java字符IO流的使用。
4. 通過正則表達式的正確使用,可以幫我們輕松的編碼,並實現自己想要的結果。
5. 如何通過Myeclipse來自動生成UML類圖。
6. 如何使用將java程序導出為jar包,並轉化為exe文件。
7. 如何編寫設計一個測試用例
這項目實現的過程中也遇到了很多問題,但由於自己的堅持不懈,
通過在網上查詢資料和同學的熱心幫助將作業完成,並在作業的完成過程中不斷的
反思和改進,使得自己在解決錯誤和問題中不斷的提升。

4. 致謝

本次作業的順利完成,主要參考老師提供的一些優秀的文章:
(地址:
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html
http://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html
http://www.cnblogs.com/math/p/se-tools-001.html

和自己通過上網搜索到的一些參考資料:
(地址:
https://blog.csdn.net/limuzi13/article/details/52912625
https://blog.csdn.net/honjane/article/details/40739337

在此,對老師和上述資料的貢獻者表示忠心的感謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM