感谢:http://blog.csdn.net/baibinboss/article/details/68947929
终于找到完美方法!!!
列出jar中指定包下的所有文件
环境
首先是jar中的文件,而不是开发环境中的文件(开发环境中的文件,eclipse中是bin目录下)。这两种情况下读文件的方式完全不同
代码
注意:如果没有打包(如在开发环境中),第8行代码protocol为file
String packagePath="com.ccc";
try {
Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(packagePath.replace(".", "/"));
while (dirs.hasMoreElements()) {
URL url=dirs.nextElement();
String protocol = url.getProtocol();
//如果该在jar中protocol为jar,如果没有打包(如在开发环境中)为file
if("jar".equals(protocol)){
//转换为JarURLConnection
JarURLConnection connection = (JarURLConnection) url.openConnection();
if(connection!=null){
// 找到包含该包路径的 jar 包
JarFile jarFile = connection.getJarFile();
if (jarFile != null) {
//得到该jar文件下面的类实体
Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries();
// 遍历该 jar 包下的所有文件、子包
while (jarEntryEnumeration.hasMoreElements()) {
/*entry的结果大概是这样:
org/
org/junit/
org/junit/rules/
org/junit/runners/
org/junit/rules/Main.class
org/junit/rules/Test.class
*/
JarEntry entry = jarEntryEnumeration.nextElement();
String path = entry.getName();
// 将路径中的 / 替换成 .
String classPath = path.replaceAll("/", ".");
/*
获取的是 当前 jar下的所有文件、路径,所以这里要过滤
只处理 前缀是指定 包路径的 class文件
*/
if (classPath.startsWith(packagePath) && !entry.isDirectory() ) {
if (classPath.endsWith(".class")) {
// 截取类名,不包含 .class
String classAllPath = classPath.substring(0, classPath.lastIndexOf("."));
//Class<?> clazz = Class.forName(classAllPath);
System.out.println(classAllPath)
}
}
}
}
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
代码分析
多个jar包
工程中可能有多个jar都包含指定包,比如:a.jar,b.jar,c.jar中都包含 com.my.utils 包,也就是说需要从多个jar中寻找指定包。
所以要用下面代码:
Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(packagePath.replace(".", "/"));
查找jar包
找到包含该包路径的 jar 包
JarFile jarFile = connection.getJarFile();
获取包路径
找到jar包后,再遍历,过滤出指定包路径的 .class 文件