1. 程式人生 > >[Java]統計Java原始檔程式碼行數,註釋行數,空白行數

[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原始檔及原始碼

百度網盤