java 实现WC

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

项目简介:

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

基本项目要求:

基本功能:(已实现)

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

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

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

扩展功能:(已实现)

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

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

高级功能:(未实现)

-x 显示图形界面 

解题思路

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

代码结构:

关键代码说明:

解析命令行参数

public class WC {
 public static void main(String[] args) {
  // TODO 自动生成的方法存根
 System.out.print("请输入需要进行的操作与操作对象:");
 Scanner sc=new Scanner(System.in);
 String temp[]=sc.nextLine().split("\\s+");
 String option=temp[0];
 String filepath=temp[1];
 String filetype=temp[2].substring(temp[2].lastIndexOf(".")+1);
 String tongpei=temp[2].substring(0, temp[2].indexOf("."));
 File file=new File(filepath);
 
 
 try {
 sc.close();
 }catch (Exception e){
  e.printStackTrace();
 };
 
 
 Map<String,Integer> map=new HashMap<String,Integer>();//通过map建立映射关系与switch调用方法
 map.put("-c",1);
 map.put("-w",2);
 map.put("-l",3);
 map.put("-s",4);
 map.put("-a",5);
 
 
 wordcount count=new wordcount();
   
 switch (map.get(option)) {
 case 1:count.charactercount(file);break;
 case 2:count.wordcount(file);break;
 case 3:count.linecount(file);break;
 case 4:count.rtcatalog(file,tongpei,filetype);break;
 case 5:count.CountSpecialLines(file);break;
 default:System.out.println("请重新按格式输入"+"\n"+"[parameter] [file_name]");
         }
 }
}

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

void charactercount(File file) {
 String str=null;
 char temp[]=null;
 int characternum=0;
 try {
  InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
  BufferedReader BF=new BufferedReader(ir);
  while((str=BF.readLine())!=null) {
  temp=str.toCharArray();
  characternum+=temp.length;
  }
  ir.close();
  BF.close();
  System.out.println("字符数:"+characternum);
 } catch (FileNotFoundException e) {
  // TODO 自动生成的 catch 块
  System.out.println("无法找到指定的文件");
  e.printStackTrace();
 }catch(Exception e) {
  e.printStackTrace();
  System.out.println("文件读取失败");
 }
 
 }
 
 void wordcount(File file) {
  String str=null;
  int wordnum=0;
  try {
   InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
   BufferedReader BF=new BufferedReader(ir);
   while((str=BF.readLine())!=null) {
   wordnum+=str.split("\\W").length;
   }
   ir.close();
   BF.close();
   System.out.println("单词数:"+wordnum);
  } catch (FileNotFoundException e) {
   // TODO 自动生成的 catch 块
   System.out.println("无法找到指定的文件");
   e.printStackTrace();
  }catch(Exception e) {
   e.printStackTrace();
   System.out.println("文件读取失败");
  }
 }
 
 

void linecount(File file) {
  int linenum=0;
  try {
   InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
   BufferedReader BF=new BufferedReader(ir);
   while(BF.readLine()!=null) {
   linenum++;
   }
   ir.close();
   BF.close();
   System.out.println("总行数:"+linenum);
  } catch (FileNotFoundException e) {
   // TODO 自动生成的 catch 块
   System.out.println("无法找到指定的文件");
   e.printStackTrace();
  }catch(Exception e) {
   e.printStackTrace();
   System.out.println("文件读取失败");
  }
 }
 
统计空白行、注释行、代码行
  void CountSpecialLines(File file) {
 int blanklines=0;
 int commentlines=0;
 int codelines=0;
 String temp=null;
 String blanklinesregex ="\\s*\\W?\\s*"; 
 String bclbeginregex="\\s*.?\\s*/\\*.*";
 String bclendregex="\\s*.?\\s*\\*/.*";
 String clregex="\\W?//.*";
 boolean blcflag=false;
 try {
/*
*首先判断是否空行,同时块注释标记是否false,
*其次判断是否进入块注释,若进入将块注释标记true
*若下一行块注释标记为true,注释行自增
*若下一行匹配到块注释结尾且块注释标记为true,注释行自增同时块注释标记改为false
*上述情况皆不成立代码行自增
 
*/
  InputStreamReader ir =new InputStreamReader(new FileInputStream(file));
  BufferedReader BF=new BufferedReader(ir);
  while((temp=BF.readLine())!=null) {
  if(temp.matches(blanklinesregex)&&(blcflag==false)) {
  blanklines++;
  }else if(temp.matches(bclbeginregex)&&temp.matches(bclendregex)) {
  commentlines++;
  blcflag=false;
  }else if(temp.matches(clregex)) {
  commentlines++; 
  }else if(temp.matches(bclbeginregex)||blcflag==true) {
  commentlines++;
  blcflag=true; 
  }else if((temp.matches(bclendregex))&&(blcflag==true)) {
  commentlines++;
  blcflag=false; 
  }else if(blcflag==false){
  codelines++;
  }
  }
  ir.close();
  BF.close();
 } catch (FileNotFoundException e) {
  // TODO 自动生成的 catch 块
  System.out.println("无法找到指定的文件");
  e.printStackTrace();
 }catch(Exception e) {
  e.printStackTrace();
  System.out.println("文件读取失败");
 }
 System.out.println("  空行  :"+blanklines);
 System.out.println("代码行:"+codelines);
 System.out.println("注释行:"+commentlines);
 }
 
递归获取指定目录下的指定文件
 
void rtcatalog(File filepath,String filename,String str) {
  File listfile[]=filepath.listFiles();
  String tongpei=null;
  if(filename==null) {
  tongpei=".*";
  }else if(filename.contains("*")) {//通过pattern模式筛选出指定文件
  tongpei=filename.replaceAll("\\*",".*");
  }else if(filename.contains("?")) {
  tongpei=filename.replaceAll("\\?",".?");
  }
  Pattern p=Pattern.compile(tongpei);
   通过通配符模式筛选指定文件
  for(File file:listfile) {
  if(file.isDirectory()) {
   rtcatalog(file,filename,str);
  }else if(file.exists()){
   Matcher m=p.matcher(file.getName());
   if(file.getName().endsWith(str)&&m.find()) {
   System.out.println("文件所在目录:"+file.getAbsolutePath());
   charactercount(file);
   wordcount(file);
   linecount(file);
   CountSpecialLines(file);
   }
  }else if(!file.exists()) {
   System.out.println("无法找到指定的路径目录下指定类型的文件");
  }
  }
 }
 
运行测试:
空文件
 只有一个字符的文件
只有一个词的文件 

 

只有一行的文件

 典型的源文件

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

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

 

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

总结:

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

猜你喜欢

转载自www.cnblogs.com/hf914/p/9648397.html
今日推荐