WC 代碼統計 java
GitHub地址
項目需求
實現一個wc統計程序,可以對文本進行相關功能的統計與分析
- 基本功能
- -c 統計字符數
- -w 統計文件詞數
- -l 統計行數
- 擴展功能
- -s 遞歸搜索目錄下面的文件
- -a 返回更復雜的數據(代碼行 / 空行 / 註釋行)
設計
主函數思路:分析命令並對-s進行預處理,得到相應的文件名字,搜索該目錄下匹配的名字,根據是否需要遞歸進行分析,再對一條命令的每一個參數進行匹配,每次從文件讀取一行字符串進行分析,再把結果打印出來。
代碼
主函數
import java.io.*; import java.util.Scanner; public class Main { private static final Scanner scanner = new Scanner(System.in); public static void main(String[] args) { String s = null; while ((s = scanner.nextLine()) != null && !s.equals("exit")) { String[] strings = s.split(" "); boolean flag = false; for (String string : strings) { if (string.equals("-a")) { flag = true; break; } } File file = new File(strings[strings.length - 1]); String fileName = file.getName(); if (!file.isDirectory()) { file = file.getParentFile(); } // doFile(file,flag,strings,fileName); if (file != null && file.isDirectory()) { File[] files = file.listFiles(pathname -> { if (pathname.isDirectory()) { return true; } return isRight(pathname, fileName); }); if (files != null) { for (File file1 : files) { doFile(file1, flag, strings, fileName); } } } else { System.out.println("輸入文件有誤"); } } } private static void doFile(File file, boolean flag, String[] args, String fileName) { if (file != null && file.isFile() && isRight(file, fileName)) { try (BufferedReader bf = new BufferedReader(new FileReader(file))) { String line; Result result = new Result(); while ((line = bf.readLine()) != null) { analyze(line, args, result); } result.print(file.getName()); } catch (IOException e) { e.printStackTrace(); } } if (file != null && flag && file.isDirectory()) { File[] files = file.listFiles(pathname -> { if (fileName.equals("") || pathname.isDirectory()) { return true; } return isRight(pathname, fileName); }); if (files != null) { for (File file1 : files) { doFile(file1, true, args, fileName); } } } } private static void analyze(String line, String[] args, Result result) { for (String arg : args) { switch (arg) { case "-w": new WordCheck(result).check(line); break; case "-l": new LineCheck(result).check(line); break; case "-c": new CharCheck(result).check(line); break; case "-s": new StructureCheck(result).check(line); break; } } } private static boolean isRight(File file, String fileName) { if (fileName.startsWith("*")) { return file.getName().endsWith(fileName.substring(fileName.lastIndexOf("."))); } else { return file.getName().equals(fileName); } } }
字符統計
public class CharCheck implements Check {
private final Result result;
public CharCheck(Result result) {
this.result = result;
}
@Override
public void check(String s) {
result.addCharLine(s.length());
}
}
根據每一行的字符串得出長度就是字符數
統計單詞
public class WordCheck implements Check { private final Result result; public WordCheck(Result result) { this.result = result; } @Override public void check(String s) { s = s.replaceAll("[\\p{Nd}\\p{Punct}\\s]", " "); result.addWord(splitWorker(s).length); } private String[] splitWorker(final String str) { if (str == null) { return null; } final int len = str.length(); if (len == 0) { return new String[]{""}; } final List<String> list = new ArrayList<>(); int sizePlus1 = 1; int i = 0, start = 0; boolean match = false; final char sep = " ".charAt(0); while (i < len) { if (str.charAt(i) == sep) { if (match) { if (sizePlus1++ == -1) { i = len; } list.add(str.substring(start, i)); match = false; } start = ++i; continue; } match = true; i++; } if (match) { list.add(str.substring(start, i)); } return list.toArray(new String[list.size()]); } }
使用正則表達式去除標點符號然後切割
統計行數
public class LineCheck implements Check {
private final Result result;
public LineCheck(Result result) {
this.result = result;
}
@Override
public void check(String s) {
result.addLine(1);
}
}
每一次就加1
統計復雜數據
public class StructureCheck implements Check { private final Result result; public StructureCheck(Result result) { this.result = result; } @Override public void check(String s) { if (s.length() == 0) { result.addBlankLine(1); return; } for (int i = 0; i < s.length(); i++) { if (i == s.length()-1 && s.charAt(i) == ‘ ‘) { result.addBlankLine(1); return; } if (s.charAt(i) != ‘ ‘) { break; } } boolean flag = false; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == ‘/‘ && i + 1 < s.length() && s.charAt(i + 1) == ‘/‘) { result.addAnnotationLine(1); return; } if (s.charAt(i) == ‘/‘ && i + 1 < s.length() && s.charAt(i + 1) == ‘*‘) { flag=true; } if (s.charAt(i) == ‘*‘ && i + 1 < s.length() && s.charAt(i + 1) == ‘/‘ && flag) { result.addAnnotationLine(1); return; } } result.addCodeLine(1); } }
統計結果
public class Result {
private Integer line;
private Integer word;
private Integer blankLine;
private Integer annotationLine;
private Integer charLine;
private Integer codeLine;
private boolean b = false;
public void print(String name) {
if (b) {
System.out.print("文件:" + name + ",");
}
if (line != null) {
System.out.print("行數:" + line + ",");
}
if (word != null) {
System.out.print("單詞數:" + word + ",");
}
if (blankLine != null) {
System.out.print("空白行:" + blankLine + ",");
}
if (annotationLine != null) {
System.out.print("註解行:" + annotationLine + ",");
}
if (codeLine != null) {
System.out.print("代碼行:" + codeLine + ",");
}
if (charLine != null) {
System.out.print("字符數量:" + charLine + ",");
}
if (b) {
System.out.println();
}
}
public void addWord(int c) {
if (word == null) {
word = 0;
b = true;
}
word += c;
}
public void addLine(int c) {
if (line == null) {
line = 0;
b = true;
}
line += c;
}
public void addBlankLine(int c) {
if (blankLine == null) {
blankLine = 0;
b = true;
}
blankLine += c;
}
public void addAnnotationLine(int c) {
if (annotationLine == null) {
annotationLine = 0;
b = true;
}
annotationLine += c;
}
public void addCharLine(int c) {
if (charLine == null) {
charLine = 0;
b = true;
}
charLine += c;
}
public void addCodeLine(int c) {
if (codeLine == null) {
codeLine = 0;
b = true;
}
codeLine += c;
}
}
測試
在控制臺下面運行代碼
-a -s -l -c -w d://*.xml ,全面測試,查找d盤下面所有的xml
部分結果
文件:SoftUpdateExCache.xml,行數:409,單詞數:1054,空白行:1,註解行:22,代碼行:386,字符數量:12603,
文件:starttips.xml,行數:87,單詞數:252,代碼行:87,字符數量:2715,
文件:TestStubConfig.xml,行數:10,單詞數:37,代碼行:10,字符數量:405,
文件:TSBlueScreenbak.xml,行數:1619,單詞數:6794,空白行:12,代碼行:1607,字符數量:58010,
文件:QMExpVul.xml,行數:1305,單詞數:50073,註解行:1301,代碼行:4,字符數量:346076,
文件:AdFilterConfigFile.xml,行數:99,單詞數:359,註解行:9,代碼行:90,字符數量:4335,
文件:tsadlibblackac.xml,行數:25,單詞數:115,代碼行:25,字符數量:948,
文件:tsadlibcss.xml,行數:2,單詞數:61707,註解行:1,代碼行:1,字符數量:419166,
文件:tsadlibcssac.xml,行數:2,單詞數:147879,註解行:1,代碼行:1,字符數量:988044,
文件:tsadlibcssbd.xml,行數:3,單詞數:1427,代碼行:3,字符數量:9210,
文件:tsadlibexcept.xml,行數:2,單詞數:2523,註解行:1,代碼行:1,字符數量:17187,
文件:tsadlibexceptac.xml,行數:2,單詞數:3606,註解行:1,代碼行:1,字符數量:25367,
文件:tsadlibfloat.xml,行數:2,單詞數:64683,註解行:1,代碼行:1,字符數量:434538,
文件:tsadlibforce.xml,行數:55,單詞數:222,註解行:6,代碼行:49,字符數量:1784,
文件:tsadlibpower.xml,行數:7735,單詞數:37795,註解行:902,代碼行:6833,字符數量:294565,
文件:tsadlibpw.xml,行數:3,單詞數:39849,註解行:2,代碼行:1,字符數量:314979,
文件:tsadlibwhite.xml,行數:2,單詞數:5712,代碼行:2,字符數量:29556,
文件:tsadlibwhiteac.xml,行數:2,單詞數:385,代碼行:2,字符數量:2234,
文件:DebugModeConfigV2.xml,行數:131,單詞數:2340,代碼行:131,字符數量:14356,
文件:DeviceDesc.xml,行數:23,單詞數:506,代碼行:23,字符數量:3094,
文件:jwlxtzqn.xml,行數:10,單詞數:211,代碼行:10,字符數量:1296,
文件:jwlxtzqnui.xml,行數:10,單詞數:97,代碼行:10,字符數量:593,
文件:UnReDevice.xml,行數:96,單詞數:1533,代碼行:96,字符數量:9637,
文件:AppMarketPluginCtrl.xml,行數:11,單詞數:109,註解行:2,代碼行:9,字符數量:845,
文件:DeepSpeedupCtrl.xml,行數:11,單詞數:75,註解行:1,代碼行:10,字符數量:617,
文件:DeepSpeedupSrcCtrl.xml,行數:11,單詞數:67,註解行:1,代碼行:10,字符數量:628,
文件:DesktopMgrPluginCtrl.xml,行數:11,單詞數:110,註解行:2,代碼行:9,字符數量:807,
文件:DocManagerPluginCtrl.xml,行數:11,單詞數:111,註解行:2,代碼行:9,字符數量:821,
文件:DownloaderMgrUICtrl.xml,行數:11,單詞數:74,註解行:1,代碼行:10,字符數量:597,
文件:FileSmashCtrl.xml,行數:17,單詞數:141,註解行:2,代碼行:15,字符數量:1136,
文件:FileUnlockerCtrl.xml,行數:15,單詞數:136,註解行:2,代碼行:13,字符數量:1094,
文件:GameLobbyPluginCtrl.xml,行數:11,單詞數:113,註解行:2,代碼行:9,字符數量:874,
文件:HWPluginCtrl.xml,行數:25,單詞數:189,註解行:2,代碼行:23,字符數量:1626,
文件:IEStartPageCtrl.xml,行數:11,單詞數:71,註解行:1,代碼行:10,字符數量:569,
文件:iToolsPluginCtrl.xml,行數:11,單詞數:103,註解行:2,代碼行:9,字符數量:777,
再特指定的一個文件測試
-a -s -w -c- l d://123.txt
內容:
public static void main(String[] args) {
//
String s = null;
while ((s = scanner.nextLine()) != null && !s.equals("exit")) {
String[] strings = s.split(" ");
boolean flag = false;
for (String string : strings) {
if (string.equals("-a")) {
flag = true;
break;
}
}
}
}
運行結果:
文件:123.txt,單詞數:38,空白行:3,註解行:1,代碼行:14,
PSP
PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 40 50
· Estimate · 估計這個任務需要多少時間 40 50
Development 開發 810 860
· Analysis · 需求分析 (包括學習新技術) 120 130
· Design Spec · 生成設計文檔 80 90
· Design Review · 設計復審 (和同事審核設計文檔) 50 60
· Coding Standard · 代碼規範 (為目前的開發制定合適的規範) 30 40
· Design · 具體設計 150 155
· Coding · 具體編碼 220 225
· Code Review · 代碼復審 40 40
· Test · 測試(自我測試,修改代碼,提交修改) 120 120
Reporting 報告 110 150
· Test Report · 測試報告 40 60
· Size Measurement · 計算工作量 30 40
· Postmortem & Process Improvement Plan · 事後總結, 並提出過程改進計劃 40 50
合計 960 1060
WC 代碼統計 java