在Java源程序中的行共有3种:
int n = 10;
/**
文档注释
*/
/*
多行注释
*/
//单行注释
如果有以下行尾单行注释的情况,将该行判定为代码行。
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文件
}
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源文件及源代码