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的更多相关文章

  1. 软件工程 wc.exe 代码统计作业

    软件工程 wc.exe 代码统计作业分享 1. Github 项目地址 https://github.com/EdwardLiu-Aurora/WordCount 更好地阅读本文,可点击这里 基本要求 ...

  2. Python实现代码统计工具——终极加速篇

    Python实现代码统计工具--终极加速篇 声明 本文对于先前系列文章中实现的C/Python代码统计工具(CPLineCounter),通过C扩展接口重写核心算法加以优化,并与网上常见的统计工具做对 ...

  3. 代码统计 (uustepcount)

    代码统计软件(uustepcount)用于 记录自己的代码数量,包括空行,代码行数,注释行数,注释百分比,代码百分比,文件大小,文件日期等. 虽然也是 分析程序的源代码,统计空行,注释行,代码行,但u ...

  4. c#代码 天气接口 一分钟搞懂你的博客为什么没人看 看完python这段爬虫代码,java流泪了c#沉默了 图片二进制转换与存入数据库相关 C#7.0--引用返回值和引用局部变量 JS直接调用C#后台方法(ajax调用) Linq To Json SqlServer 递归查询

    天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找到合适天气预报接口一切都是小意思,说干就干,立马跟学生沟通价格. ​ ​不过谈报价的过程中,差点没让我一口老血喷键盘上,话说我们程序猿的人 ...

  5. Android学习笔记_32_通过WebView实现JS代码与Java代码互相通信

    webview两种实现方法,覆盖onKeyDown()方法 缓存 WebSettings应用注意的几个问题 1.要实现JS代码与Java代码互相通信,需要通过Android的WebView控件,在视图 ...

  6. 快速识别烂项目!试试这款项目代码统计IDEA插件

    编程是一个很奇妙的事情,大部分的我们把大部分时间实际都花在了复制粘贴,而后修改代码上面. 很多时候,我们并不关注代码质量,只要功能能实现,我才不管一个类的代码有多长.一个方法的代码有多长. 因此,我们 ...

  7. Android C代码回调java方法

    本文将讲述下列三种C代码回调java方法 1.c代码回调java空方法 2.c代码回调java int类型参数方法 3.c代码回调javaString类型参数方法 方法都差不多,先看c代码回调java ...

  8. python 练习(一)代码统计工具的实现

    最近部门成立了一个python学习小组,旨在让大家在做项目中开始成长起来,于是老大就给布置了第一个小任务:代码统计工具,具体的需求如下: 需求: . 能够统计指定目录下C++程序的代码行数. . C+ ...

  9. 博友的 编写高质量代码 改善java程序的151个建议

    编写高质量代码 改善java程序的151个建议 http://www.cnblogs.com/selene/category/876189.html

随机推荐

  1. 在android开发中添加外挂字体

    1.在项目目录中,右键app——New——Folder—— Assets Folder 2.把.ttf或者.oft文件拷进这个assets文件夹 3.在onCreate()中 Typeface typ ...

  2. 关于OPC自动化接口编程(OPCDAAuto.dll)几点注意问题

    为了能够在工作中方便的应用OPC和充分的理解OPC的开发流程.内部机制,这两天正在研究开发OPC客户端程序,一般我们开发OPC客户端程序有以下几种方式: (1)       使用OPCNetAPI,需 ...

  3. 安装ruby-pg报错解决

    ruby用pgsql做orm的时候,需要安装ruby-pg库,默认编译安装会提示缺少xx头文件 max下,我用的傻瓜式pgsql.app gem install pg -- --with-pg-con ...

  4. [转载]交换机STP协议

    注:之前做一个项目,测试部使用2个公司的交换机,H3C和H公司的,H公司的交换机是OEM H3C的交换机,正常来说两者使用没有区别. 但是使用中发现,如果设备的多个对外业务网口连接的交换机的聚合网口, ...

  5. 在windows环境中使用varnish

    varnish 的windows 版本下载地址:   http://sourceforge.net/projects/cygvarnish/files/windows-zip-bundle/     ...

  6. Java多线程总结【转】

    多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程 ...

  7. web开发 那些年基于Redis的Provider库

    因为session基于本地cache,以前我们自己写分布式缓存,或者数据库存储,或者cookie加密存储,来保存用户状态信息,但较少的直接通过创建一个继承 SessionStateStoreProvi ...

  8. Py修行路 python基础 (二十三)模块与包

    一.模块 1)定义: 模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 2)为何要用模块: 退出python解释器然后重新进入,那之前定义的函数或者变量都将丢失,因 ...

  9. Sql Server 2005如何导入DBF文件?

    提问者采纳   select * into 要生成的SQL表名 from OPENROWSET('MICROSOFT.JET.OLEDB.4.0','dBase IV;HDR=NO;IMEX=2;DA ...

  10. 「小程序JAVA实战」 小程序wxss样式文件的使用(七)

    转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-07/ 细说下微信小程序的wxss样式文件.源码:https://github.com/liming ...