Soft personal project work WC (Java implementation)

WC individual events (jJAVA achieve)

A, Github Address: https://github.com/GordonKowk/WC_Item

 


Two, PSP form

 

PSP2.1 Personal Software Process Stages Estimated time consuming (minutes) The actual time-consuming (minutes)
Planning plan 30 36
· Estimate • Estimate how much time this task requires 30 30
Development Develop 960 784
· Analysis · demand analysis  50 50
· Design Spec Generate design documents 30 43
· Design Review · Design Review  20 20
· Coding Standard · Code Specification 20 20
· Design · Specific design 80 60
· Coding · Specific coding 750 681
· Code Review · Code Review 30 30
· Test · Test (self-test, modify the code, submit modifications) 180 180
Reporting report 60 85
· Test Report · testing report 60 60
· Size Measurement · Computing workload 20 20
· Postmortem & Process Improvement Plan · Hindsight, and propose process improvement plan 40 40
total   2360 2159

 


 

Third, the problems encountered & problem-solving ideas:

1) started a project when listening distressed, because the first time I went to run a java file (OMG, I found that the regulation is to Taiyuan, the command line) with cmd, but after learning is also relatively simple. Project made a number of java files on the command line to compile more, and finally selected the main class to run. Because I use MyEclipse, write java comes with the package, the package must be removed after not being given cmd enable runtime.

2) Whatever the function, to write a switch to judge each Processro, starting from simple, basic functions -c, -w, -l, -a function are our classroom contact, and how the contents of the file into the buffer is learned. You can say different, there is -a statistical judgment on the comment line, "\\" if there is one line of text can be learned by judgment, "/ * ...... * /" you can first determine the header comments to make the judgment in Notes status, go looking for the end. Function determination code is determined as a single element (the first element arr [0] is usually "-c" "-, this is not a path string w" and the like can not provide file) being given, I the "-x" graphical interface and "exit" two judgments release switch.

3) recursive call. Statistics in line with the current folder under the required documents, including subfolders. For the current directory, as arr [length-1] is the last element, that is, you would have wanted the file path statistics. Separated by the String class substring (), LastIndexOf () method of the parent folder name and file extension, with file.isFile () and file.isDirectory () and other statistical methods to judge the current file directory folder number and name, file number and extension of the same name, these data are placed in different array of strings inside. For a child file, I create a recursive method sonProcessor (), good statistics and statistical file folder name suffix before accepting data. The same recursive method for an array of folders where each folder Road King once again statistics, if there is, continue to call their own (doing so will make the output statistics from the beginning of the innermost folder), until there is no file. Finally, the output data of the problem, as I just wrote a text input stream, gave way to four function calls, resulting in the statistical data would have been out of a total of a 3552 word document, reached in the second statistics over 8000, and finally I separated four different text transport stream only solve the problem (I do not know if there is a better way, because so much of the text delivery is certainly unrealistic).

4) wildcard problem. I started writing would be more to consider whether to go after the "regular expression" (actually a regular expression is more judgmental than the switch), but I do recursive function can be found substring String class (), LastIndexOf () method for wildcards "*", the file path to intercept the last occurrence of "\" and. "" middle of nowhere, is the "*" wildcards, so before you can add a switch to determine if it is "*" appeared, direct call recursion.

5) Finally, a graphical interface, personal feeling is relatively simple, and I designed the interface with six buttons and comes with a text field, respectively -c, -w, -l, -a, comprehensive and exit functions I define an integer Type, function buttons have given listeners can call FileChooser, and each button will change the value of output corresponding statistics Type of content.

 


 

Fourth, Design and Implementation

Only three major categories, the main class Wc, function and interface class Function_Directory class GUI_Frame.

The main call flow:

Fifth, test run

Test files include: three java files, a txt file, two unrelated folders nested directories (three java files, one with three sub-folders and files java)

Wc.java run inside the CMD interface:

 

 

Basic functions and extensions -a:

 

 

 

-S recursive call with wildcards "*":

 

 

 graphic interface:

 

 

 

Wc.java

复制代码
static boolean TRUE_OR_NOT = true;
 
 public static void main(String[] args){
  System.out.println("*-------------------WC统计-------------------*");
  System.out.println("基础功能说明:");
  System.out.println("  统计字符数:-c [您要查找的文件路径]");
  System.out.println("  统计词数:  -w [您要查找的文件路径]");
  System.out.println("  统计行数:  -l [您要查找的文件路径]");
  System.out.println("");
  System.out.println("拓展功能说明:");
  System.out.println("  统计空行、代码行、注释行:    -a [您要查找的文件路径]");
  System.out.println("  递归处理:   -s [您要查找的文件路径]");
  System.out.println("");
  System.out.println("高级功能说明:");
  System.out.println("  图形化界面:-x");
  System.out.println("");
  System.out.println("若想退出程序请输入:退出");
  System.out.println("*--------------------------------------------*");
  System.out.println("请输入指令:"); 
  while(TRUE_OR_NOT){
   Scanner command = new Scanner(System.in);
   String[] arr = command.nextLine().split("\\s");
   int len = arr.length;
   Function_Directory FD = new Function_Directory();
   FD.commandProcessor(arr,len,0,arr[arr.length-1]); //把数据都交给FD对象里面
  }
 }
复制代码

GUI_Frame.java

复制代码
private static final long serialVersionUID = 1L;
 
 Toolkit          kit        = Toolkit.getDefaultToolkit();
 Dimension         screenSize   = kit.getScreenSize();
 static  JTextArea   textArea     = new JTextArea();
 private JPanel      chooseBar    = new JPanel();
 private JButton     count_c      = new JButton("字符数");
 private JButton     count_w     = new JButton("词数");
 private JButton     count_l      = new JButton("行数");
 private JButton     count_a     = new JButton("拓展功能");
 private JButton     count_all    = new JButton("总结");
 private JButton     count_close  = new JButton("关闭");
 private Font     buttonFont     = new Font("宋体",Font.BOLD,25);
 int       charNum        = 0;
 int       wordNum         = 0;
 int       lineNum        = 0;
 int       blankLineNum      = 0;
 int       codeLineNum       = 0;
 int       annotationLineNum  = 0;
 int       Type    = 0;
 ArrayList<Integer>    resultList    = null;
 
 
 GUI_Frame(){
  setTitle("WC统计");
  setSize(2*screenSize.width/4,3*screenSize.height/4);   
  setLocation(2*screenSize.width/4,screenSize.height/8);
  initEventListeners();     
  add(chooseBar,BorderLayout.NORTH);
  initChooseBar();
     initTextArea();
 }
 
 private void initChooseBar(){            //顶部选项栏设置
  chooseBar.add(count_c);
  chooseBar.add(count_w);
  chooseBar.add(count_l);
  chooseBar.add(count_a);
  chooseBar.add(count_all);
  chooseBar.add(count_close);
        count_c.setFont(buttonFont);
        count_w.setFont(buttonFont);
        count_l.setFont(buttonFont);
        count_a.setFont(buttonFont);
        count_all.setFont(buttonFont);
        count_close.setFont(buttonFont);
    }
 
 private void initTextArea(){
        textArea.setFont(new Font("宋体", Font.PLAIN, 30));
        textArea.setMargin(new Insets(3,10,3,10));
        textArea.setLineWrap(true);
        textArea.setDragEnabled(true);
        JScrollPane panel = new JScrollPane(textArea,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        getContentPane().add(panel, BorderLayout.CENTER);
    }
 
 private void initEventListeners(){
  count_c.addActionListener(  this::countC );
  count_w.addActionListener(  this::countW );
  count_l.addActionListener(  this::countL );
  count_a.addActionListener(  this::countA );
  count_all.addActionListener( this::countAll );
  count_close.addActionListener( this::countClose);
 }
 
 private void countC(ActionEvent event){
  Type = 1;
  CountStart();
 }
 private void countW(ActionEvent event){
  Type = 2;
  CountStart();
 }
 private void countL(ActionEvent event){
  Type = 3;
  CountStart();
 }
 private void countA(ActionEvent event){
  Type = 4;
  CountStart();
 }
 private void countAll(ActionEvent event){
  Type = 5;
  CountStart();
 }
 private void countClose(ActionEvent event){
  Type = 0;
  System.exit(0);
 }
 
 public void CountStart(){
  JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        chooser.showDialog(new JLabel(), "选择要统计的文件");
        File file = chooser.getSelectedFile();
        try{
   String encoding = "GBK";
   InputStreamReader readFile = new InputStreamReader(new FileInputStream(file),encoding);
   BufferedReader fileContent = new BufferedReader(readFile);
   switch(Type){
   case 1:
    charNum = Function_Directory.charsCounter(fileContent);
    textArea.append(file+":\n"+"字符数:" + charNum + "\n\n");
    break;
   case 2:
    wordNum = Function_Directory.wordsCounter(fileContent);
    textArea.append(file+":\n词数:" + wordNum+"\n\n");
    break;
   case 3:
    lineNum = Function_Directory.linesCounter(fileContent);
    textArea.append(file+":\n行数:" + lineNum+"\n\n");
    break;
   case 4:
    resultList = Function_Directory.Expand_Count(fileContent);
    blankLineNum = resultList.get(0);
    codeLineNum = resultList.get(1);
    annotationLineNum = resultList.get(2);
    textArea.append(file+":\n空行数:" + blankLineNum + "\n代码行数:"
      + codeLineNum + "\n注释行数" + annotationLineNum+"\n\n");
    break;
   case 5:
    charNum = Function_Directory.charsCounter(fileContent);
    wordNum = Function_Directory.wordsCounter(fileContent);
    lineNum = Function_Directory.linesCounter(fileContent);
    resultList = Function_Directory.Expand_Count(fileContent);
    blankLineNum = resultList.get(0);
    codeLineNum = resultList.get(1);
    annotationLineNum = resultList.get(2);
    textArea.append(file+":\n"+"字符数:" + charNum + "\n词数:"
      + wordNum + "\n行数:" + lineNum + "\n空行数:" + blankLineNum + "\n代码行数:"
      + codeLineNum + "\n注释行数" + annotationLineNum+"\n"); 
   }   
  }catch(IOException e){
    System.out.println("文件路径错误或者文件不支持喔~");
    e.printStackTrace();
  }
 }
 
 public static void main(String[] args) {
  GUI_Frame GF = new GUI_Frame();
  GF.setVisible(true);
 }
复制代码

Function_Directory.java

复制代码
public class Function_Directory {
 public void commandProcessor(String[] arr,int len,int start,String fileName){
  if(arr[0].equals("-x")){      //由于只输入一个元素会报错,“-x”和“退出”先提前判断
   GUI_Frame GF = new GUI_Frame();    //一个图形化界面
   GF.setVisible(true);
  } else if(arr[0].equals("退出")) { Wc.TRUE_OR_NOT = false;
  } else{
   try{
    for(int i = start;i < len-1||i == 0;i++){
     String fileUrl = arr[arr.length-1].substring(arr[arr.length-1].lastIndexOf("\\")+1,arr[arr.length-1].lastIndexOf("."));
     System.out.println(fileUrl);
     if(fileUrl.equals("*")) recursiveProcessor(arr); //判断通用符号“*”
     else{
      String encoding = "GBK";
      File file = new File(fileName);
      InputStreamReader readFile = new InputStreamReader(new FileInputStream(file),encoding);
      BufferedReader fileContent = new BufferedReader(readFile);   
     switch(arr[i]){
      case "-c":
       charsCounter(fileContent);
       break;
      case "-w":
       wordsCounter(fileContent);
       break;
      case "-l":
       linesCounter(fileContent);
       break;
      case "-a":
       Expand_Count(fileContent);
       break;
      case "-s":
       recursiveProcessor(arr);
       break;
      default:break;
     }
    }}
   }catch(Exception e){
    System.out.println(arr[0]+"不是功能指令喔~,看看是不是哪里输入错误了。");
    e.printStackTrace();
   }
  }
 }
 
 static int charsCounter(BufferedReader fileContent) throws IOException{
  String  lineCount  = null;
  int  charNum  = 0;
  while((lineCount  = fileContent.readLine()) != null){
   lineCount   = lineCount.trim();
   for(int i = 0;i < lineCount.length();i++){
    char ch  = lineCount.charAt(i);
    if(ch != '\n' && ch != '\t' && ch != ' ')
     charNum++;
   }
  }
  System.out.println("字符数:" + charNum);
  return charNum;
 }
 
 static int wordsCounter(BufferedReader fileContent) throws IOException{
  String  REGEX   = "[a-zA-Z]+\\b";  //判断词的正则表达式
  String  lineCount  = null;
  int  wordNum  = 0;
  Pattern pattern  = Pattern.compile(REGEX);
  while((lineCount = fileContent.readLine()) != null){
    lineCount  = lineCount.trim();
   Matcher matcher = pattern.matcher(lineCount);
   while(matcher.find()){
    wordNum++;
   }
  }
  System.out.println("词数:" + wordNum);
  return wordNum;
 }
 
 static int linesCounter(BufferedReader fileContent) throws IOException{
  int  lineNum  = 0;
  String  lineCount  = null;
  while((lineCount = fileContent.readLine()) != null){ lineNum++; }
  System.out.println("行数:" + lineNum);
  return  lineNum;
 }
 
 static ArrayList<Integer> Expand_Count(BufferedReader fileContent)throws IOException{
  String  lineCount  = null;
  ArrayList<Integer>  resultList   = new ArrayList<Integer>();
  boolean    isComment   = false;
  int  codeLineNum   = 0;
  int  blankLineNum   = 0;
  int  annotationLineNum  = 0;
  while((lineCount = fileContent.readLine()) != null){   //对注释行的判断
   if(lineCount.contains("/*")){
    annotationLineNum++;
    isComment = true;
   } else if(isComment){
    annotationLineNum++;
    if(lineCount.contains("*/")){ isComment = false; }
   } else if(lineCount.contains("//")){
    annotationLineNum++;
   } else if(lineCount.trim().length() > 1){
    codeLineNum++;
   } else{
    blankLineNum++;
   }
  } 
  System.out.println("空行数:" + blankLineNum);
  System.out.println("代码行数:" + codeLineNum);
  System.out.println("注释行数:" + annotationLineNum);
  resultList.add(blankLineNum);
  resultList.add(codeLineNum);
  resultList.add(annotationLineNum);
  return resultList;
 }
 
 public void recursiveProcessor(String[] arr) throws IOException{
  int   LA    = arr.length;
  int   n    = 0;
  String   fileUrl   = arr[LA-1].substring(0,arr[LA-1].lastIndexOf("\\")); //找到文件路径最先出现“\”的位置
  String   fileEnd   = arr[LA-1].substring(arr[LA-1].lastIndexOf("."));  //找到文件路径最先出现“.”的位置
        List<File>  fileList   = new ArrayList<File>();
        File   file    = new File(fileUrl);
        File[]   files    = file.listFiles();
        String[]    names   = file.list();
        String[] CompletNames  = null;
        for (File f : files) {
         if (f.isDirectory()){ n++;    }
        }
        CompletNames    = new String[n];
        n       = 0;
        if (files == null) {}
        for (File f : files) {
            if (f.isFile()&&f.getName().endsWith(fileEnd)) {  fileList.add(f); }
            if (f.isDirectory()){
             CompletNames[n] = arr[LA-1].substring(0,arr[LA-1].lastIndexOf("\\"))+"\\"+f.getName();
             System.out.println(CompletNames[n]);
             n++;
            }
        }
        for (File f1 : fileList) {
         System.out.println(fileUrl+"\\"+f1.getName());
   String encoding = "GBK";
   InputStreamReader rC = new InputStreamReader(new FileInputStream(f1),encoding);
   InputStreamReader rW = new InputStreamReader(new FileInputStream(f1),encoding);
   InputStreamReader rL = new InputStreamReader(new FileInputStream(f1),encoding);
   InputStreamReader rA = new InputStreamReader(new FileInputStream(f1),encoding);
    BufferedReader C = new BufferedReader(rC);
    BufferedReader W = new BufferedReader(rW);
    BufferedReader L = new BufferedReader(rL);
    BufferedReader A = new BufferedReader(rA);
     charsCounter(C);
     wordsCounter(W);
     linesCounter(L);
     Expand_Count(A);
   C.close();        //我试过只写一个文本输入流,统计结果会累积,数据错误
   W.close();        //由于写入太多输入流,希望想找到更好的办法
   L.close();
   A.close();       
        }
  System.out.println("*-----------------------------*");
  if (CompletNames!=null) sonProcessor(CompletNames,fileEnd); 
 }
 private void sonProcessor(String[] Names,String End) throws IOException { 
  String[]     N     = Names;    //寻找子文件,并把子文件里面符合要求的文件统计出来
  int    LengthA   = N.length;    //这里我运用了递归,但是发现是先递归到最里层才开始统计
  for(int i=0;i<Names.length;i++){
   int   n    = 0;
   String   fileUrl   = N[i];
   String   fileEnd   = End;
   List<File>  fileList   = new ArrayList<File>();
         File   file    = new File(fileUrl);
         File[]   files    = file.listFiles();
         String[]    names   = file.list();
         String[] CompletNames  = null;
         for (File f : files) {
          if (f.isDirectory()){ n++; }
         }
         CompletNames    = new String[n];
         n       =0; 
         if (files == null) {}
         for (File f : files) {
             if (f.isFile()&&f.getName().endsWith(fileEnd)) {  fileList.add(f); }
             if (f.isDirectory()){
              CompletNames[n]  = N[i]+"\\"+f.getName();
              System.out.println(CompletNames[n]);
              n++;
             }
         }
         if (CompletNames!=null)  sonProcessor(CompletNames,fileEnd);
         for (File f1 : fileList) {
    System.out.println(N[i]+"\\"+f1.getName());
    String encoding = "GBK";
    InputStreamReader rC = new InputStreamReader(new FileInputStream(f1),encoding);
    InputStreamReader rW = new InputStreamReader(new FileInputStream(f1),encoding);
    InputStreamReader rL = new InputStreamReader(new FileInputStream(f1),encoding);
    InputStreamReader rA = new InputStreamReader(new FileInputStream(f1),encoding);
     BufferedReader C = new BufferedReader(rC);
     BufferedReader W = new BufferedReader(rW);
     BufferedReader L = new BufferedReader(rL);
     BufferedReader A = new BufferedReader(rA);
      charsCounter(C);
      wordsCounter(W);
      linesCounter(L);
      Expand_Count(A);
    C.close();
    W.close();
    L.close();
    A.close();
    System.out.println("*-----------------------------*");
         }
  }
 }
复制代码

 六、项目总结:

   这次项目让我感受最深的是做这个项目的计划,先给自己一个规划,做出要想做的框架流程,想好自己应该干嘛,用多少时间,应该怎么去测试,以前的课设我是没有注意到这些的,这也让我看到做一个项目的严谨性。之前的java程序我都是通过设计图形化界面去运行的,没有像这次在命令行里面运行,学会了如何在命令行编译与运行java文件。递归调用的实现也是我印象最深刻的,文件夹和文件的路径由于循环让我自己都搞晕了,不断调试,不断找准切分位置,不断有报错,文件夹数组长度不能过长,路径不能错误,有时数据会卡住循环进行。递归的实现是我用时最多的部分。但是因为想去搞懂,从网上找资料,询问同学,学到不少,也能想出适合自己的方法。现在是个人项目,我期待在后面的项目能收获更多。

Guess you like

Origin www.cnblogs.com/GordonKowk/p/11570256.html