可以指定扫描的包路径,默认方法从根路径开始扫描。
1. 定义文件的递归方法
这个方法接收两个参数当前文件和存储文件的列表。利用java内File类的方法,递归查询该文件的文件名或者文件夹内的文件,详情看代码
/**
* 递归获取所有文件
*
* @param file 当前文件
* @param files 存储文件的列表
*/
private static void getFiles(File file, List<File> files) {
// 判断是否是文件,并且是否是以.class结尾的文件
if (file.isFile() && file.getName().endsWith(".class")) {
// 是则添加到列表中
files.add(file);
}
// 判断是否是目录
if (file.isDirectory()) {
// 获取到目录内所有的文件
File[] listFiles = file.listFiles();
// 若不为空,则递归遍历
if (listFiles != null) {
// 遍历所有文件
for (File f : listFiles) {
// 递归遍历
getFiles(f, files);
}
}
}
}
2. 定义包扫描的主要方法
这里的包扫描获取所有的指定绝对路径包下的.class文件。packageAbsolutePath是指包的绝对路径,例如:E:\Documents\NetBeansProjects\cinemaSellTickets\src\main\java\com。详情看注释
/**
* 扫描指定路径下的所有class文件
*
* @param packageAbsolutePath 包的绝对路径
* @return 所有class文件名(全限定类名)
*/
private static List<String> scan(String packageAbsolutePath){
// 存储所有class文件的列表
List<File> fileList = new ArrayList<>();
// 存储所有class文件名的列表
List<String> classNames = new ArrayList<>();
// 获取到指定路径
File file = new File(packageAbsolutePath);
// 递归获取所有文件
getFiles(file, fileList);
/// 这里可以替换为forEach,效率更高一些
// 遍历所有文件,获取到全限定类名
for (File f : fileList) {
// 去掉路径前缀,并去掉.class后缀,替换\为.,添加到文件名集合内
String path = f.getPath();
path = path.substring(ROOT_PATH.length() - 1)
.replace(".class", "")
.replace("\\", ".");
classNames.add(path);
}
// 返回所有的class文件的全限定类名
return classNames;
}
3. 定义供外部调用的方法
这里有俩方法,这里的ROOT_PATH见总代码,不传参数从根路径开始查找,带包路径则从包路径下开始查询。
/**
* 扫描根路径下所有class文件
*
* @return 所有class文件名(全限定类名)
*/
public static List<String> packageScan() {
return scan(ROOT_PATH);
}
/**
* 扫描指定包下的所有class文件
*
* @param packageName 包名 例:(com.cinema.ticket)
* @return 所有class文件名(全限定类名)
*/
public static List<String> packageScan(String packageName){
// 得到包的绝对路径
String packagePath = ROOT_PATH + packageName.replace(".", "/");
return scan(packagePath);
}
附录:
/**
* 用于包扫描的工具类
*/
public class PackageScan {
/**
* 项目根路径
*/
private static final String ROOT_PATH = ClassLoader.getSystemResource("").getPath();
/**
* 私有构造器,防止被实例化
*/
private PackageScan() {}
/**
* 扫描根路径下所有class文件
* @return 所有class文件名(全限定类名)
*/
public static List<String> packageScan() {
return scan(ROOT_PATH);
}
/**
* 扫描指定包下的所有class文件
*
* @param packageName 包名 例:(com.cinema.ticket)
* @return 所有class文件名(全限定类名)
*/
public static List<String> packageScan(String packageName){
// 得到包的绝对路径
String packagePath = ROOT_PATH + packageName.replace(".", "/");
return scan(packagePath);
}
/**
* 扫描指定路径下的所有class文件
*
* @param packageAbsolutePath 包的绝对路径
* @return 所有class文件名(全限定类名)
*/
private static List<String> scan(String packageAbsolutePath){
// 存储所有class文件的列表
List<File> fileList = new ArrayList<>();
// 存储所有class文件名的列表
List<String> classNames = new ArrayList<>();
// 获取到指定路径
File file = new File(packageAbsolutePath);
// 递归获取所有文件
getFiles(file, fileList);
/// 这里可以替换为forEach,效率更高一些
// 遍历所有文件,获取到全限定类名
for (File f : fileList) {
// 去掉路径前缀,并去掉.class后缀,替换\为.,添加到文件名集合内
String path = f.getPath();
path = path.substring(ROOT_PATH.length() - 1)
.replace(".class", "")
.replace("\\", ".");
classNames.add(path);
}
// 返回所有的class文件的全限定类名
return classNames;
}
/**
* 递归获取所有文件
*
* @param file 当前文件
* @param files 存储文件的列表
*/
private static void getFiles(File file, List<File> files) {
// 判断是否是文件,并且是否是以.class结尾的文件
if (file.isFile() && file.getName().endsWith(".class")) {
// 是则添加到列表中
files.add(file);
}
// 判断是否是目录
if (file.isDirectory()) {
// 获取到目录内所有的文件
File[] listFiles = file.listFiles();
// 若不为空,则递归遍历
if (listFiles != null) {
// 遍历所有文件
for (File f : listFiles) {
// 递归遍历
getFiles(f, files);
}
}
}
}
}
鄙人表达能力有限,还望各位不喜勿喷。欢迎大家指出问题(抱拳)