java 实现WC

GitHub地址:https://github.com/hanfeng98/WC

项目简介:

实现一个统计目标文件字符数、单词数、行数及其他特殊数据的的命令行程序。并能处理多个文件,同时还能识别一般的通配符。

基本项目要求:

基本功能:(已实现)

-c  <文件路径>  统计文件中字符的数量。

-w <文件路径>  统计文件中单词的数量。

-l   <文件路径>  统计文件的总行数。

扩展功能:(已实现)

-s   <搜寻目录路径>  <文件类型名>  批量处理符合条件的文件。(可识别一般通配符:*、?)

-a   <文件路径>  统计文件代码行、空白行、注释行的数量。

高级功能:(未实现)

-x 显示图形界面 

解题思路

项目开始后,先考虑了载入文本的方法,一是把代码内容全部通过输入输出流导入到一个长字符串中,二是通过输入输出流的readline方法进行边输入边统计,并且把统计功能封装成方法,通过调用方法进行统计,方法中通过使用正则表达式来区分目标对象。命令行输入通过map建立映射结合switch调用功能。

代码结构:

 

关键代码说明:

解析命令行参数

 

 1 public class WC {
 2  public static void main(String[] args) {
 3   // TODO 自动生成的方法存根
 4  System.out.print("请输入需要进行的操作与操作对象:");
 5  Scanner sc=new Scanner(System.in);
 6  String temp[]=sc.nextLine().split("\\s+");
 7  String option=temp[0];
 8  String filepath=temp[1];
 9  String filetype=temp[2].substring(temp[2].lastIndexOf(".")+1);
10  String tongpei=temp[2].substring(0, temp[2].indexOf("."));
11  File file=new File(filepath);
12  
13  
14  try {
15  sc.close();
16  }catch (Exception e){
17   e.printStackTrace();
18  }; 
19  
20  
21  Map<String,Integer> map=new HashMap<String,Integer>();//通过map建立映射关系与switch调用方法
22  map.put("-c",1);
23  map.put("-w",2);
24  map.put("-l",3);
25  map.put("-s",4);
26  map.put("-a",5);
27  
28  
29  wordcount count=new wordcount();
30     
31  switch (map.get(option)) {
32  case 1:count.charactercount(file);break;
33  case 2:count.wordcount(file);break;
34  case 3:count.linecount(file);break;
35  case 4:count.rtcatalog(file,tongpei,filetype);break;
36  case 5:count.CountSpecialLines(file);break;
37  default:System.out.println("请重新按格式输入"+"\n"+"[parameter] [file_name]");
38          }
39  }
40  
41 }
42  
43  

 

统计行数、字符数、单词数

 1 void charactercount(File file) {
 2  String str=null;
 3  char temp[]=null;
 4  int characternum=0;
 5  try {
 6   InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
 7   BufferedReader BF=new BufferedReader(ir);
 8   while((str=BF.readLine())!=null) {
 9   temp=str.toCharArray();
10   characternum+=temp.length;
11   }
12   ir.close();
13   BF.close();
14   System.out.println("字符数:"+characternum);
15  } catch (FileNotFoundException e) {
16   // TODO 自动生成的 catch 块
17   System.out.println("无法找到指定的文件");
18   e.printStackTrace();
19  }catch(Exception e) {
20   e.printStackTrace();
21   System.out.println("文件读取失败");
22  }
23  
24  }
25  
26  void wordcount(File file) {
27   String str=null;
28   int wordnum=0;
29   try {
30    InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
31    BufferedReader BF=new BufferedReader(ir);
32    while((str=BF.readLine())!=null) {
33    wordnum+=str.split("\\W").length;
34    }
35    ir.close();
36    BF.close();
37    System.out.println("单词数:"+wordnum);
38   } catch (FileNotFoundException e) {
39    // TODO 自动生成的 catch 块
40    System.out.println("无法找到指定的文件");
41    e.printStackTrace();
42   }catch(Exception e) {
43    e.printStackTrace();
44    System.out.println("文件读取失败");
45   }
46  }
47  
48  
49 void linecount(File file) {
50   int linenum=0;
51   try {
52    InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
53    BufferedReader BF=new BufferedReader(ir);
54    while(BF.readLine()!=null) {
55    linenum++;
56    }
57    ir.close();
58    BF.close();
59    System.out.println("总行数:"+linenum);
60   } catch (FileNotFoundException e) {
61    // TODO 自动生成的 catch 块
62    System.out.println("无法找到指定的文件");
63    e.printStackTrace();
64   }catch(Exception e) {
65    e.printStackTrace();
66    System.out.println("文件读取失败");
67   }
68  }
69  

 

统计空白行、注释行、代码行
 
 1 void CountSpecialLines(File file) {
 2  int blanklines=0;
 3  int commentlines=0;
 4  int codelines=0;
 5  String temp=null;
 6  String blanklinesregex ="\\s*\\W?\\s*"; 
 7  String bclbeginregex="\\s*.?\\s*/\\*.*";
 8  String bclendregex="\\s*.?\\s*\\*/.*";
 9  String clregex="\\W?//.*";
10  boolean blcflag=false;
11  try {
12 /*
13 *首先判断是否空行,同时块注释标记是否false,
14 *其次判断是否进入块注释,若进入将块注释标记true
15 *若下一行块注释标记为true,注释行自增
16 *若下一行匹配到块注释结尾且块注释标记为true,注释行自增同时块注释标记改为false
17 *上述情况皆不成立代码行自增
18  
19 */
20   InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
21   BufferedReader BF=new BufferedReader(ir);
22   while((temp=BF.readLine())!=null) {
23   if(temp.matches(blanklinesregex)&&(blcflag==false)) {
24   blanklines++;
25   }else if(temp.matches(bclbeginregex)&&temp.matches(bclendregex)) {
26   commentlines++;
27   blcflag=false;
28   }else if(temp.matches(clregex)) {
29   commentlines++; 
30   }else if(temp.matches(bclbeginregex)||blcflag==true) {
31   commentlines++;
32   blcflag=true; 
33   }else if((temp.matches(bclendregex))&&(blcflag==true)) {
34   commentlines++;
35   blcflag=false; 
36   }else if(blcflag==false){
37   codelines++;
38   }
39   }
40   ir.close();
41   BF.close();
42  } catch (FileNotFoundException e) {
43   // TODO 自动生成的 catch 块
44   System.out.println("无法找到指定的文件");
45   e.printStackTrace();
46  }catch(Exception e) {
47   e.printStackTrace();
48   System.out.println("文件读取失败");
49  }
50  System.out.println("  空行  :"+blanklines);
51  System.out.println("代码行:"+codelines);
52  System.out.println("注释行:"+commentlines);
53  }

 

 
递归获取指定目录下的指定文件
 
 1 void rtcatalog(File filepath,String filename,String str) {
 2   File listfile[]=filepath.listFiles();
 3   String tongpei=null;
 4   if(filename==null) {
 5   tongpei=".*";
 6   }else if(filename.contains("*")) {//通过pattern模式筛选出指定文件
 7   tongpei=filename.replaceAll("\\*",".*");
 8   }else if(filename.contains("?")) {
 9   tongpei=filename.replaceAll("\\?",".?");
10   } 
11   Pattern p=Pattern.compile(tongpei);

 


   通过通配符模式筛选指定文件
 
 1  for(File file:listfile) {
 2   if(file.isDirectory()) {
 3    rtcatalog(file,filename,str);
 4   }else if(file.exists()){
 5    Matcher m=p.matcher(file.getName());
 6    if(file.getName().endsWith(str)&&m.find()) {
 7    System.out.println("文件所在目录:"+file.getAbsolutePath());
 8    charactercount(file);
 9    wordcount(file);
10    linecount(file);
11    CountSpecialLines(file);
12    }
13   }else if(!file.exists()) {
14    System.out.println("无法找到指定的路径目录下指定类型的文件");
15   }
16   }
17  }

 

 
运行测试:
空文件
 只有一个字符的文件
只有一个词的文件 

 

只有一行的文件

 典型的源文件

递归遍历指定目录指定类型的文件

通配符 通过通配符筛选走文件

 

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

30

40

· Estimate

· 估计这个任务需要多少时间

  15

20

Development

开发

300

360

· Analysis

· 需求分析 (包括学习新技术)

60

90

· Design Spec

· 生成设计文档

30

40

· Design Review

· 设计复审 (和同事审核设计文档)

20

20

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

15

20

· Design

· 具体设计

60

80

· Coding

· 具体编码

300

300

· Code Review

· 代码复审

120

180

· Test

· 测试(自我测试,修改代码,提交修改)

90

90

Reporting

报告

90

120

· Test Report

· 测试报告

60

45

· Size Measurement

· 计算工作量

10

5

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

20

15

合计

 

1220

1425

 

总结:

本以为此项目会比较简单,但实际进行起来发现设计阶段的设计不足,查阅资料后知道要用正则表达式和文件输入流来解决问题,但是具体操作是发现正则表达式的表达式有些许疑问,特别是对于特定文件的筛选时,控制符号与正则表达式的转换让我耗费了不少时间,这让我深感基础的薄弱。

 

 

 

转载于:https://www.cnblogs.com/hf914/p/9648397.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值