本例子来源于观看马士兵视频教程,视频中并未使用递归,故无法统计包含子目录的情况。在此添加递归完善。
源代码为
import java.io.*;
/**
* 统计一个目录下(含子目录)所有java源文件中代码行数
*
*/
public class CodeCounter {
private static int whiteLines = 0;// 空白行数
private static int commentLines = 0;// 注释行数
private static int normalLines = 0;// 有效代码行数
public static void main(String[] args) {
File folder = new File("D:\\codetest");// 要统计的源目录路径
recur(folder);// 递归该目录,统计其中代码行数
System.out.println("Total Lines:"
+ (whiteLines + commentLines + normalLines));
System.out.println("WhiteLines: " + whiteLines);
System.out.println("CommentLines: " + commentLines);
System.out.println("NormalLines: " + normalLines);
}
// 递归方法 若源路径为目录,则递归,直至不包含子目录
public static void recur(File file) {
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory() == true) {
recur(files[i]);
} else if ((files[i].isFile() == true)
&& files[i].getName().matches(".*\\.java$")) {
parse(files[i]);
}
}
}
public static void parse(File file) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = "";
boolean isComment = false; // 标记/*...*/注释不在同一行的情况
while ((line = br.readLine()) != null) {
line = line.trim();
// if(line.matches("\\n[\\s| ]*\\r"))
if (line.matches("^[\\s&&[^\\n]]*"))
// \t\n\x0B\f\r”开始且不含换行符
// java中\n表示换行,\s匹配任意的空白符 包括换行符
{
whiteLines++;
} else if (line.startsWith("/*") && line.endsWith("*/"))// 注释行:形如同一行中/*...*/
{
commentLines++;
} else if (line.startsWith("/*") && !line.endsWith("*/"))// 注释行:形如/*...
{
commentLines++;
isComment = true;
} else if (true == isComment) {
commentLines++; // 注释行:包含在/*和*/之间的注释行
if (line.endsWith("*/")) {
isComment = false; // 注释行: 形如 ...*/
}
} else if (line.startsWith("//")) {
commentLines++; // 注释行: 形如//....
} else {
normalLines++; // 有效代码行
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
br = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}