要求
因为只是一个小程序,所以代码全部放在同一个包下
此博文文字内容较少,因为注释比较多,如果有问题可私信博主
效果展示
此程序会生成一个 result 文件夹及 it.txt 文件,分析的内容保存到此处
Utils 工具类
import java.io.File;
import java.util.Scanner;
public class Utils {
// 显示菜单信息
public static void showMenu() {
System.out.println("----------MENU----------");
System.out.println("1. 分析目录中的源文件程序");
System.out.println("2. 查看分析结果");
System.out.println("0. 退出程序");
System.out.println("------------------------");
}
// 判断输入目录是否正确
public static File getPath() {
String pathName = null;
File root = null;
while (true) {
System.out.print("请输入目录路径:");
Scanner scanner = new Scanner(System.in);
pathName = scanner.nextLine();
root = new File(pathName);
if (root.isFile() || !root.exists()) {
System.out.println("[" + pathName + "]不是目录名或不存在!");
} else {
break;
}
}
return root;
}
// 要求输入的是数字
public static int getChoice() {
Scanner scanner = new Scanner(System.in);
int choice;
// 输入的数据可能有误
try {
choice = scanner.nextInt();
} catch (Exception e) {
System.out.println("输入有误!请重新输入");
return getChoice();
}
return choice;
}
}
Main
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class Main {
public static void main(String[] args) {
while (true) {
Utils.showMenu();
System.out.print("请选择:");
int choice = Utils.getChoice();
if (choice < 0 || choice > 2) {
System.out.println("输入有误!请重新输入");
continue;
}
switch (choice) {
case 1:
// 得到正确的目录
File path = Utils.getPath();
// 分析 java 源程序
FileAnalysis fileAnalysis = null;
try {
fileAnalysis = new FileAnalysis();
fileAnalysis.analyzeFile(path);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
case 2:
// 输出文件内容
ShowFiles showFiles = null;
try {
showFiles = new ShowFiles();
showFiles.showFiles();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
case 0:
return;
default:
System.out.println("输入有误!请重新输入");
break;
}
}
}
}
FileAnalysis 文件分析
import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class FileAnalysis {
// java 文件数,总行数,空白行数,总字节数
private long javaFiles, lineInFiles, blankLines, bytes;
// 当前目录文件路径,使用 URLDecoder.decode 解决中文路径乱码的问题
private String currentFilePath = URLDecoder.decode(this.getClass().getResource("").getPath(), "utf-8");
// 当前目录文件
private File currentFile = new File(currentFilePath);
public FileAnalysis() throws UnsupportedEncodingException {
}
// 分析文件
public void analyzeFile(File path) throws IOException {
// 创建 result 目录
File result = new File(currentFile.getAbsolutePath() + "\\result");
result.mkdirs();
// 创建结果文件
File file = new File(result.getAbsolutePath() + "\\" + path.getName() + ".txt");
file.createNewFile();
// 得到输出流用于写文件
OutputStream os = new FileOutputStream(file);
String content = "[" + path.getAbsolutePath() + "] Result:\n\nFiles detail:\n";
// 先转为 byte 数组再写入结果文件
os.write(content.getBytes(StandardCharsets.UTF_8));
// 遍历 path 目录下所有文件
searchJavaFiles(os, path, 0);
content = "Total:\n\t" + javaFiles + " Java Files\n"
+ "\t" + lineInFiles + " lines in files\n"
+ "\t" + blankLines + " blank lines\n"
+ "\t" + bytes + " bytes\n";
os.write(content.getBytes(StandardCharsets.UTF_8));
// 关闭流
os.close();
}
// 遍历 path 目录下所有 java 源文件,os:输出流,level:层级
private void searchJavaFiles(OutputStream os, File path, int level) throws IOException {
String content = "";
// 每深入一层子目录,要缩进4个空格
for (int i = 0; i < level; i++) {
content += " ";
}
content += "+" + path.getName() + "\n";
os.write(content.getBytes(StandardCharsets.UTF_8));
File[] files = path.listFiles();
if (null == files) {
return;
}
// 对文件进行排序
List fileList = Arrays.asList(files);
Collections.sort(fileList, new Comparator<File>() {
@Override
public int compare(File o1, File o2) {
if (o1.isDirectory() && o2.isFile())
return -1;
if (o1.isFile() && o2.isDirectory())
return 1;
return o1.getName().compareTo(o2.getName());
}
});
int length = files.length;
for (int i = 0; i < length; i++) {
if (files[i].isDirectory()) {
// 递归遍历文件目录
searchJavaFiles(os, files[i], level + 1);
} else {
if (files[i].getName().endsWith(".java")) {
codeAnalyze(os, files[i], level + 1);
}
}
}
}
// 分析源文件
public void codeAnalyze(OutputStream os, File file, int level) throws IOException {
javaFiles++;
int rows = countRows(file);
int blanks = countBlanks(file);
bytes += file.length();
String content = "";
for (int i = 0; i < level; i++) {
content += " ";
}
String str1 = "-" + file.getName();
str1 = String.format("%-40s", str1);
content += str1;
content += "Total:" + String.format("%5d", rows) + ", Blank:" + String.format("%5d", blanks)
+ ", " + String.format("%9d", file.length()) + " Bytes\n";
os.write(content.getBytes(StandardCharsets.UTF_8));
}
// 总行数
public int countRows(File file) throws IOException {
BufferedReader input = new BufferedReader(new FileReader(file));
int rows = 0;
while (input.readLine() != null) {
rows++;
}
lineInFiles += 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++;
}
blankLines += blanks;
return blanks;
}
}
ShowFiles 读取展示 result 文件
import java.io.*;
import java.net.URLDecoder;
public class ShowFiles {
// 当前目录文件路径,使用 URLDecoder.decode 解决中文路径乱码的问题
private String currentFilePath = URLDecoder.decode(this.getClass().getResource("").getPath(), "utf-8");
// 当前目录文件
private File currentFile = new File(currentFilePath);
public ShowFiles() throws UnsupportedEncodingException {
}
public void showFiles() throws IOException {
File result = new File(currentFile.getAbsolutePath() + "\\result");
File[] files = result.listFiles();
if (null == files || 0 == files.length) {
System.out.println("还没有分析结果!");
return;
}
int length = files.length;
System.out.println("---------------------------");
for (int i = 0; i < length; i++) {
System.out.println((i + 1) + "." + files[i].getName());
}
System.out.println("---------------------------");
while (true) {
int choice = Utils.getChoice();
if (choice == 0) {
return;
}
if (choice < 0 || choice > length) {
System.out.println("输入有误!请重新输入");
continue;
}
// 读取文件内容并显示
BufferedReader input = new BufferedReader(new FileReader(files[choice - 1]));
String line = null;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
return;
}
}
}