WordCount--统计输入文件的字符数、行数、单词数(java)--初级功能
碼云地址:
https://gitee.com/YuRenDaZ/WordCount
個(gè)人PSP表格:
| PSP2.1 | PSP階段 | 預(yù)估耗時(shí) (分鐘) | 實(shí)際耗時(shí) (分鐘) |
| Planning | 計(jì)劃 | ?180 | ?120 |
| · Estimate | · 估計(jì)這個(gè)任務(wù)需要多少時(shí)間 | ?180 | ?120 |
| Development | 開(kāi)發(fā) | ?580 | ?440 |
| · Analysis | · 需求分析 (包括學(xué)習(xí)新技術(shù)) | ?180 | ?60 |
| · Design Spec | · 生成設(shè)計(jì)文檔 | ?40 | ?30 |
| · Design Review | · 設(shè)計(jì)復(fù)審 (和同事審核設(shè)計(jì)文檔) | ?20 | ?20 |
| · Coding Standard | · 代碼規(guī)范 (為目前的開(kāi)發(fā)制定合適的規(guī)范) | ?20 | ?10 |
| · Design | · 具體設(shè)計(jì) | ?20 | ?20 |
| · Coding | · 具體編碼 | ?180 | ?200 |
| · Code Review | · 代碼復(fù)審 | ?30 | ?40 |
| · Test | · 測(cè)試(自我測(cè)試,修改代碼,提交修改) | ?90 | ?60 |
| Reporting | 報(bào)告 | ?90 | ?70 |
| · Test Report | · 測(cè)試報(bào)告 | ?40 | ?30 |
| · Size Measurement | · 計(jì)算工作量 | ?20 | ?10 |
| · Postmortem & Process Improvement Plan | · 事后總結(jié), 并提出過(guò)程改進(jìn)計(jì)劃 | ?30 | ?30 |
| ? | 合計(jì) | ?850 | ?630 |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
一、功能需求分析
WordCount的需求可以概括為:對(duì)程序設(shè)計(jì)語(yǔ)言源文件統(tǒng)計(jì)字符數(shù)、單詞數(shù)、行數(shù),統(tǒng)計(jì)結(jié)果以指定格式輸出到默認(rèn)文件中,以及其他擴(kuò)展功能,并能夠快速地處理多個(gè)文件。可執(zhí)行程序命名為:wc.exe,該程序處理用戶需求的模式為:
wc.exe [parameter] [input_file_name]
存儲(chǔ)統(tǒng)計(jì)結(jié)果的文件默認(rèn)為result.txt,放在與wc.exe相同的目錄下。
詳細(xì)分析:
?功能 -c?? :返回文件 file.c 的字符數(shù)
?功能 -w?? :返回文件 file.c 的單詞總數(shù)
?功能 -l???? :返回文件 file.c 的總行數(shù)
?功能 -o??? :將結(jié)果輸出到指定文件outputFile.txt
?要求 : 1. -o 功能后面必須有輸出文件路徑的參數(shù)。
2.在沒(méi)有 -o 命令指定輸出文件的時(shí)候默認(rèn)將結(jié)果保存在exe同目錄下的result.txt。
3.可以滿足多個(gè)文件同時(shí)查詢。
注意:
空格,水平制表符,換行符,均算字符。
由空格或逗號(hào)分割開(kāi)的都視為單詞,且不做單詞的有效性校驗(yàn),例如:thi#,that視為用逗號(hào)隔開(kāi)的2個(gè)單詞。
?
二、程序設(shè)計(jì)
A:大概設(shè)計(jì)
? 1):程序由工具類和主函數(shù)類構(gòu)成。
???? 2):程序使用main的入口參數(shù)。
B:詳細(xì)設(shè)計(jì)
1):將每一個(gè)“-?”指令對(duì)應(yīng)一個(gè)方法。
? 2):將功能方法寫(xiě)在一個(gè)類里,作為工具類。
? 3):使用條件判斷語(yǔ)句來(lái)處理命令。
? 4):用集合存儲(chǔ)需要查詢的文件,以方便進(jìn)行添加和遍歷。
? 5):程序主要邏輯在main函數(shù)中進(jìn)行。(邏輯并不非十分復(fù)雜)
三、程序編碼(編碼并不是最好的實(shí)現(xiàn)方法,希望各位同學(xué)能指出不足之處,我們大家一起進(jìn)步!)
- 主函數(shù)邏輯主要是由循環(huán)語(yǔ)句和條件判斷語(yǔ)句完成。代碼如下: 1 import java.util.HashSet;
2 import java.util.Set;
3
4 public class WordCount {
5
6 public static void main(String[] args) {
7 CountUtil countUtil = new CountUtil();//實(shí)例化工具類對(duì)象
8 Set<String> file_paths = new HashSet<String>() ; //創(chuàng)建用于存儲(chǔ)輸入文件的集合
9 String Output_file = "result.txt"; //存儲(chǔ)輸出文件名(默認(rèn)為同目錄下的result.txt文件)
10 String Result = ""; //存儲(chǔ)查詢結(jié)果
11 boolean isCharacters = false; //是否查詢字符數(shù)
12 boolean isLines = false; //是否查詢行數(shù)
13 boolean isWords = false; //是否查詢單詞數(shù)
14 for (int i = 0;i<args.length;i++) { //循環(huán)讀取入口參數(shù)
15 if (args[i].startsWith("-")) { //判斷是否是命令
16 switch (args[i]) {
17 case "-c":
18 isCharacters = true; //是-c指令,激活查詢條件
19 break;
20 case "-l":
21 isLines = true; //是-l指令,激活查詢條件
22 break;
23 case "-w":
24 isWords =true; //是-w指令,激活查詢條件
25 break;
26 case "-o":
27 if(!args[i+1].startsWith("-")) //-o指令 判斷后面是否有指定輸出文件
28 {
29 Output_file = args[i+1]; //args[i+1]必須為輸出文件
30 i++;
31 }else {
32 System.out.println("input error !"); //提示輸入錯(cuò)誤并終止程序
33 System.exit(0);
34 }
35 break;
36 default:
37 System.out.println("input error !");
38 break;
39 }
40 }
41 else file_paths.add(args[i]); //將不屬于命令的字符串存儲(chǔ)在集合里面
42 }
43
44 if (isWords) {
45 Result+=countUtil.ReturnWords(file_paths)+"\r\n"; //調(diào)用查詢單詞方法,并做字符串拼接
46 }
47 if (isLines) {
48 Result+=countUtil.ReturnLines(file_paths)+"\r\n"; //調(diào)用查詢行數(shù)方法,并做字符串拼接
49 }
50 if (isCharacters) {
51 Result+=countUtil.ReturnCharacters(file_paths)+"\r\n"; //調(diào)用查詢字符數(shù)方法,并做字符串拼接
52 }
53 System.out.println(Result);
54 countUtil.OutputFile(Output_file, Result); //將結(jié)果輸出到文件
55 }
56 }
?
- 在工具類中各方法的實(shí)現(xiàn):(基本上都是基于IO流的操作)
ReturnCharacters方法,返回查詢結(jié)果(String類型),參數(shù)為輸入文件的集合。代碼如下:
public String ReturnCharacters(Set<String> file_paths) {int Count = 0,bytes = 0;String result = "";//用于存儲(chǔ)返回值byte [] tem = new byte[20*1024];//用存儲(chǔ)讀取數(shù)據(jù)的定常字節(jié)數(shù)組int len = tem.length;//得到tem的長(zhǎng)度以避免循環(huán)時(shí)反復(fù)調(diào)用.lengthFileInputStream in = null;//聲明一個(gè)文件輸入流try {for (String file_path : file_paths) {in = new FileInputStream(file_path);//得到字符輸入流,string為文件絕對(duì)路徑 while ((bytes = in.read(tem,0,len))!=-1) {Count+=bytes;//統(tǒng)計(jì)累計(jì)讀取的字符數(shù) }result += file_path+",字符數(shù):"+Count+" ";//結(jié)果字符串拼接Count = 0;} } catch (FileNotFoundException e) {System.out.println("有文件輸入錯(cuò)誤,請(qǐng)核對(duì)!(如果不會(huì)使用相對(duì)路徑,請(qǐng)使用絕對(duì)路徑)"); //檢查到文件不存在,提示錯(cuò)誤System.exit(0); //結(jié)束程序} catch (IOException e) {e.printStackTrace();}finally {try {in.close();//關(guān)閉輸入流} catch (IOException e) {e.printStackTrace();}}return result;} 返回字符數(shù)ReturnWords方法,返回查詢結(jié)果(String類型),參數(shù)為輸入文件的集合。代碼如下:
1 public String ReturnWords(Set<String> file_paths){ 2 int Count = 0; //存儲(chǔ)單詞數(shù) 3 String result = "";//存儲(chǔ)返回值 4 StringBuffer saveString = new StringBuffer();//因?yàn)閟tring具有不可變性,用StringBuffer來(lái)進(jìn)行讀取的添加 5 String tmp = ""; //緩存字符串 6 FileInputStream in = null;//聲明文件字符輸入流 7 InputStreamReader isr = null;//聲明字節(jié)輸入流 8 BufferedReader bis = null;//聲明緩存輸入流 9 try { 10 for (String file_path : file_paths) { //foreach循環(huán)遍歷數(shù)組 11 in = new FileInputStream(file_path);//實(shí)例化文件輸入流對(duì)象 12 isr = new InputStreamReader(in);//實(shí)例化字節(jié)輸入流對(duì)象 13 bis = new BufferedReader(isr);//實(shí)例化緩存輸入流對(duì)象 14 while ((tmp=bis.readLine())!=null) { //readLine()返回讀取的字節(jié),若沒(méi)有了就返回null 15 saveString.append(tmp); //將新讀出來(lái)的數(shù)據(jù)接在已保存的后面 16 } 17 tmp = saveString.toString(); //用字符串存儲(chǔ),以用split方法區(qū)分單詞 18 String [] total = tmp.split("[\\s+,\\.\n]");//用正則表達(dá)式將字符串按單詞格式分開(kāi) 19 Count = total.length; //字符串?dāng)?shù)組長(zhǎng)度就是單詞個(gè)數(shù) 20 result += file_path+",單詞數(shù):"+Count+" "; //結(jié)果字符串拼接 21 Count = 0; 22 } 23 } catch (FileNotFoundException e) { 24 System.out.println("有文件輸入錯(cuò)誤,請(qǐng)核對(duì)!(如果不會(huì)使用相對(duì)路徑,請(qǐng)使用絕對(duì)路徑)"); //檢查到文件不存在,提示錯(cuò)誤 25 System.exit(0); //結(jié)束程序 26 } catch (IOException e) { 27 e.printStackTrace(); 28 }finally { 29 try { 30 in.close();//關(guān)閉文件字符輸入流 31 isr.close();//關(guān)閉字節(jié)輸入流 32 bis.close();//關(guān)閉緩存輸入流 33 } catch (IOException e) { 34 e.printStackTrace(); 35 } 36 37 } 38 return result; 39 } 返回單詞數(shù)ReturnLines方法,返回查詢結(jié)果(String類型),參數(shù)為輸入文件的集合。代碼如下:
1 public String ReturnLines(Set<String> file_paths) { 2 int Count = 0; 3 String result = ""; 4 FileInputStream in = null;//聲明文件字符輸入流 5 InputStreamReader isr = null;//聲明字節(jié)輸入流 6 BufferedReader bis = null;//聲明緩存輸入流 7 try { 8 for (String file_path : file_paths) { //foreach循環(huán)遍歷數(shù)組 9 in = new FileInputStream(file_path);//實(shí)例化文件輸入流對(duì)象 10 isr = new InputStreamReader(in);//實(shí)例化字節(jié)輸入流對(duì)象 11 bis = new BufferedReader(isr);//實(shí)例化緩存輸入流對(duì)象 12 while (bis.readLine()!=null) { 13 Count++; 14 } 15 result += file_path+",行數(shù):"+Count+" "; //結(jié)果字符串拼接 16 Count = 0; 17 } 18 } catch (FileNotFoundException e) { 19 System.out.println("有文件輸入錯(cuò)誤,請(qǐng)核對(duì)!(如果不會(huì)使用相對(duì)路徑,請(qǐng)使用絕對(duì)路徑)"); //檢查到文件不存在,提示錯(cuò)誤 20 System.exit(0); //結(jié)束程序 21 } catch (IOException e) { 22 e.printStackTrace(); 23 }finally { 24 try { 25 in.close();//關(guān)閉文件字符輸入流 26 isr.close();//關(guān)閉字節(jié)輸入流 27 bis.close();//關(guān)閉緩存輸入流 28 } catch (IOException e) { 29 e.printStackTrace(); 30 } 31 32 } 33 return result; 34 } 返回行數(shù)OutputFile方法,將結(jié)果保存在文件中,返回boolean型,參數(shù)為文件路徑和內(nèi)容。代碼如下:
1 public boolean OutputFile(String File_path,String Context){ 2 File OutputFile = new File(File_path); //創(chuàng)建File對(duì)象 3 FileOutputStream os = null; //聲明 文件輸出流 4 byte [] a = null; //用于存儲(chǔ)Context轉(zhuǎn)化的byte字節(jié)數(shù)組 5 try { 6 if(!OutputFile.exists()) { //判斷文件是否存在 7 OutputFile.createNewFile(); //不存在,創(chuàng)建一個(gè)文件 8 } 9 os = new FileOutputStream(OutputFile); //獲得輸出流對(duì)象 10 a = Context.getBytes(); //將Context轉(zhuǎn)化為Byte數(shù)組,以便寫(xiě)入文件 11 os.write(a); //將byte數(shù)組寫(xiě)入文件 12 } catch (IOException e) { 13 e.printStackTrace(); 14 }finally { 15 try { 16 os.close(); //關(guān)閉輸出流 17 } catch (IOException e) { 18 e.printStackTrace(); 19 } 20 } 21 return true; 22 } 23 } 輸出結(jié)果文件?
四、代碼測(cè)試
代碼調(diào)試方法參照 https://www.cnblogs.com/xy-hong/p/7197725.html
由于是使用的main函數(shù)的入口參數(shù),所以之前并未接觸過(guò)這類方式的程序編寫(xiě)。在經(jīng)過(guò)查閱后在改文章上找到了調(diào)試方式。具體操作再次不予詳述,請(qǐng)參照以上鏈接。
? 因?yàn)橐蟛荒苡靡延械脺y(cè)試框架進(jìn)行測(cè)試,所以就自己設(shè)計(jì)了一個(gè)測(cè)試類。在類中,分為單獨(dú)針對(duì)每一個(gè)需要測(cè)試得方法都設(shè)計(jì)一個(gè)測(cè)試方法,然后再主函數(shù)中調(diào)用達(dá)到一次性全部測(cè)試得效果。
import java.util.HashSet; import java.util.Set;public class ProTest {public static void main(String[] args) {testOutputFile();testReturnCharacters();testReturnLines();testReturnWords();}public static void testReturnCharacters() {Set<String> file_paths = new HashSet<String>();String file1 = "F://test.c";String file2 = "F://test.java";file_paths.add(file2);file_paths.add(file1);System.out.println("testReturnCharacters():");System.out.println(new CountUtil().ReturnCharacters(file_paths));}public static void testReturnWords() {Set<String> file_paths = new HashSet<String>();String file1 = "F://test.c";String file2 = "F://test.java";file_paths.add(file2);file_paths.add(file1);System.out.println("testReturnWords():");System.out.println(new CountUtil().ReturnWords(file_paths));}public static void testReturnLines() {Set<String> file_paths = new HashSet<String>();String file1 = "F://test.c";String file2 = "F://test.java";file_paths.add(file2);file_paths.add(file1);System.out.println("testReturnLines():");System.out.println(new CountUtil().ReturnLines(file_paths));}public static void testOutputFile() {String file_path = "result.txt";String context = "OutPutFile test !";if(new CountUtil().OutputFile(file_path, context)) {System.out.println("File output success !");}else {System.out.println("error !");}} }
?
直接運(yùn)行測(cè)試類,得到結(jié)果:
?
用例測(cè)試:
文件中的結(jié)果:
?
?
?
?
?
?
五、將項(xiàng)目導(dǎo)出為exe可執(zhí)行文件
依賴工具:exe4j
? 參考方法:手把手教你如何把java代碼,打包成jar文件以及轉(zhuǎn)換為exe可執(zhí)行文件(注意:改博客中沒(méi)有指出32位和64位系統(tǒng)的差別,具體如下)
六、項(xiàng)目與遠(yuǎn)程庫(kù)同步過(guò)程(碼云)
有關(guān)git和碼云項(xiàng)目的遠(yuǎn)程連接以及工作提交等相關(guān)操作參考Git和Github簡(jiǎn)單教程(該教程非常的詳細(xì),值得推薦。)
?本項(xiàng)目一共有三次項(xiàng)目提交,分別是初始代碼、復(fù)審代碼、測(cè)試后修改的最終代碼。
七、個(gè)人總結(jié)
第一次撰寫(xiě)博客有很多迷茫之處,但是在撰寫(xiě)博客的過(guò)程中我發(fā)現(xiàn)這其實(shí)是對(duì)整個(gè)項(xiàng)目過(guò)程的一次回顧與反思。在以前的作業(yè)中,通常都是寫(xiě)完代碼測(cè)試完后就不再關(guān)注,也不會(huì)反在完成項(xiàng)目的途中犯過(guò)什么樣的錯(cuò)誤。每當(dāng)下次遇到同樣的問(wèn)題還是會(huì)被困擾住,所以我覺(jué)得寫(xiě)博客是真的有必要的。雖然寫(xiě)出來(lái)的博客沒(méi)人看,沒(méi)人會(huì)在意,但是這并不是開(kāi)始學(xué)習(xí)的我們的目的。我們的目的就在于回顧過(guò)程,反思過(guò)程中的錯(cuò)誤,讓項(xiàng)目的過(guò)程在我們腦海里留下更深的印象。最后,這次的作業(yè)的量還是算比較大的,但是卻真的能感覺(jué)到有很多的收獲。很多東西都是詞不達(dá)意的,真的用心體會(huì)過(guò)就能明白。
? 感謝以上引用的各鏈接的作者們,希望你們的文章能幫助更多的人。
轉(zhuǎn)載于:https://www.cnblogs.com/YuRenX/p/9693943.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的WordCount--统计输入文件的字符数、行数、单词数(java)--初级功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [导入]C# Tips 2 右键单击li
- 下一篇: zip4j实现多线程压缩