[Java]统计Java源文件代码行数,注释行数,空白行数

题目

1.各种行的说明

在Java源程序中的行共有3种:

(1)代码行,可运行的Java源代码。例如:

int n = 10;

(2) 注释行,3种注释均可。例如:

 /**
  文档注释
 */

 /*
   多行注释
 */
 
 //单行注释

(3)空行,既无代码,也无注释;


2.特殊行的处理方法

如果有以下行尾单行注释的情况,将该行判定为代码行。

int number;  //number表示人数
int n;       /*n表示数量*/

如果有以下行尾多行注释的情况,第1行判定为代码行,第二行判定为注释行。

int number;  /* number为整型
                表示人数 */

假设被分析程序源码无其他特殊情况,如:

int /*人数*/ number;

代码实现

代码中不使用正则表达式进行简化操作,而是使用逻辑判断.
思路还是先在给定的目录下递归寻找所有的java文件,将其加入到ArrayList中.用循环对ArrayList中每一个java文件分别统计总行数,注释行数,空白行数,代码行数.虽然可以只扫描一遍文件就能得到不同的行数,但是为了代码的耦合度和美观,每个统计都分开一个方法.

构造方法

    ArrayList<File> fileList;
    File root;
    public CodeAnalyzer(String pathName) {
     root = new File(pathName);  //给定的目录
     fileList = new ArrayList<>(); //储存java文件
 }

递归搜索目录下的java文件

    public void searchFiles() {
        File[] files = root.listFiles();
        int length = files.length;
        for (int i = 0; i < length; i++) {
            if (files[i].isDirectory()) {
                root = files[i];
                searchFiles();
            } else {
                if (files[i].getName().endsWith(".java"))
                    fileList.add(files[i]);
            }
        }
    }

统计单个文件的总行数

    public int countRows(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        int rows = 0;
        while (input.readLine() != null) {
            rows++;
        }
        return rows;
    }

统计单个文件的空白行数


    public int countBlanks(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        int blanks = 0;
        String line = null;
        while ((line = input.readLine()) != null) {
            if (line.trim().equals("")) blanks++;
        }
        return blanks;
    }

统计单个文件的注释行数

    public int countComments(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        int comments = 0;
        String line = null;
        while ((line = input.readLine()) != null) {
            line = line.trim();
            if (line.startsWith("//")) { //单行注释
                comments++;
            } else if (line.startsWith("/*")) { //多行及文档注释
                comments++;
                while (!line.endsWith("*/")) {
                    line = input.readLine().trim();
                    comments++;
                }
            } else if (line.contains("/*")) { //行尾多行注释
                line = input.readLine().trim();
                if (line.endsWith("*/")) comments++;
            }

        }
        return comments;
    }

总的统计与输出

    public void codeAnalyze() {
        double rowsCount = 0;
        double commentsCount = 0;
        double blanksCount = 0;
        double codesCount = 0;
        DecimalFormat df = new DecimalFormat("#.##");
        for (File file : fileList) {
            try {
                rowsCount += countRows(file);
                blanksCount += countBlanks(file);
                commentsCount += countComments(file);
                codesCount = rowsCount - blanksCount - commentsCount;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //输出结果
        System.out.println("源程序文件总行数:" + (int) rowsCount);
        System.out.println("代码行数:" + (int) codesCount + ",占" + df.format(codesCount / rowsCount*100) + "%");
        System.out.println("注释行数:" + (int) commentsCount + ",占" + df.format(commentsCount / rowsCount*100) + "%");
        System.out.println("空白行数:" + (int) blanksCount + ",占" + df.format(blanksCount / rowsCount*100) + "%");
    }

主函数

    public static void main(String[] args) {
        String pathName = "E:\\1";
        CodeAnalyzer analyzer = new CodeAnalyzer(pathName);
        analyzer.searchFiles(); //搜索文件
        analyzer.codeAnalyze(); //统计文件
    }

完整代码

import java.io.*;
import java.util.ArrayList;
import java.text.DecimalFormat;

public class CodeAnalyzer {
    ArrayList<File> fileList;
    File root;

    public CodeAnalyzer(String pathName) {
        root = new File(pathName);
        fileList = new ArrayList<>();
    }

    public void searchFiles() {
        File[] files = root.listFiles();
        int length = files.length;
        for (int i = 0; i < length; i++) {
            if (files[i].isDirectory()) {
                root = files[i];
                searchFiles();
            } else {
                if (files[i].getName().endsWith(".java"))
                    fileList.add(files[i]);
            }
        }
    }

    public void codeAnalyze() {
        double rowsCount = 0;
        double commentsCount = 0;
        double blanksCount = 0;
        double codesCount = 0;
        DecimalFormat df = new DecimalFormat("#.##");
        for (File file : fileList) {
            try {
                rowsCount += countRows(file);
                blanksCount += countBlanks(file);
                commentsCount += countComments(file);
                codesCount = rowsCount - blanksCount - commentsCount;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //输出结果
        System.out.println("源程序文件总行数:" + (int) rowsCount);
        System.out.println("代码行数:" + (int) codesCount + ",占" + df.format(codesCount / rowsCount * 100) + "%");
        System.out.println("注释行数:" + (int) commentsCount + ",占" + df.format(commentsCount / rowsCount * 100) + "%");
        System.out.println("空白行数:" + (int) blanksCount + ",占" + df.format(blanksCount / rowsCount * 100) + "%");
    }

    public int countRows(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        int rows = 0;
        while (input.readLine() != null) {
            rows++;
        }
        return rows;
    }

    public int countBlanks(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        int blanks = 0;
        String line = null;
        while ((line = input.readLine()) != null) {
            if (line.trim().equals("")) blanks++;
        }
        return blanks;
    }

    public int countComments(File file) throws IOException {
        BufferedReader input = new BufferedReader(new FileReader(file));
        int comments = 0;
        String line = null;
        while ((line = input.readLine()) != null) {
            line = line.trim();
            if (line.startsWith("//")) {//单行注释
                comments++;
            } else if (line.startsWith("/*")) { //多行及文档注释
                comments++;
                while (!line.endsWith("*/")) {
                    line = input.readLine().trim();
                    comments++;
                }
            } else if (line.contains("/*")) { //下行尾多行注释
                line = input.readLine().trim();
                if (line.endsWith("*/")) comments++;
            }

        }
        return comments;
    }

    public static void main(String[] args) {
        String pathName = "E:\\TestFile";
        CodeAnalyzer analyzer = new CodeAnalyzer(pathName);
        analyzer.searchFiles();
        analyzer.codeAnalyze();
    }

}

测试结果

对测试样例进行统计得到结果.:在这里插入图片描述
在这里插入图片描述

源码下载

包含用于测试的java源文件及源代码

百度网盘

猜你喜欢

转载自blog.csdn.net/xHibiki/article/details/82933760