我尝试从classpath(web-inf / classes / dir)获取文件列表。
Enumeration<URL> en = getClass().getClassLoader().getResources("dir");
但是,除了此文件夹中的元素外,唯一的元素是文件夹本身。有没有办法可以获取文件列表,或者唯一的方法是逐个访问文件。因为当我尝试在同一文件夹中引用某个文件时,我可以轻松访问其内容。
答案 0 :(得分:1)
您无法以递归方式浏览类路径上的目录。
请参阅此帖子:How to use ClassLoader.getResources() correctly?
但是,如果您知道正在查看JAR文件,则可以直接将其作为存档打开并浏览文件。
有人想出了这个问题的有用答案:Get all of the Classes in the Classpath
您可以调整此代码以浏览类路径上的所有JAR文件和目录,并自行为您的目录名应用一些过滤器。该示例将列出gnu.trove。*包中的所有类:
import java.io.File;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class Test
{
public static void main(String[] args)
{
final String dirname = "gnu.trove.";
findClasses(new Visitor<String>() {
@Override
public boolean visit(String classname)
{
if (classname.startsWith(dirname)) {
System.out.println(classname);
}
return true;
}
});
}
public interface Visitor<T>
{
public boolean visit(T t);
}
public static void findClasses(Visitor<String> visitor)
{
String classpath = System.getProperty("java.class.path");
String[] paths = classpath.split(System.getProperty("path.separator"));
String javaHome = System.getProperty("java.home");
File file = new File(javaHome + File.separator + "lib");
if (file.exists()) {
findClasses(file, file, true, visitor);
}
for (String path : paths) {
file = new File(path);
if (file.exists()) {
findClasses(file, file, true, visitor);
}
}
}
private static boolean findClasses(File root, File file,
boolean includeJars, Visitor<String> visitor)
{
if (file.isDirectory()) {
for (File child : file.listFiles()) {
if (!findClasses(root, child, includeJars, visitor)) {
return false;
}
}
} else {
if (file.getName().toLowerCase().endsWith(".jar") && includeJars) {
JarFile jar = null;
try {
jar = new JarFile(file);
} catch (Exception ex) {
}
if (jar != null) {
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
int extIndex = name.lastIndexOf(".class");
if (extIndex > 0) {
if (!visitor.visit(name.substring(0, extIndex)
.replace("/", "."))) {
return false;
}
}
}
}
} else if (file.getName().toLowerCase().endsWith(".class")) {
if (!visitor.visit(createClassName(root, file))) {
return false;
}
}
}
return true;
}
private static String createClassName(File root, File file)
{
StringBuffer sb = new StringBuffer();
String fileName = file.getName();
sb.append(fileName.substring(0, fileName.lastIndexOf(".class")));
file = file.getParentFile();
while (file != null && !file.equals(root)) {
sb.insert(0, '.').insert(0, file.getName());
file = file.getParentFile();
}
return sb.toString();
}
}
以下是一些忽略JAR文件并只浏览类路径上目录文件的代码:
import java.io.File;
public class Test
{
public static void main(String[] args)
{
findClasses(new Visitor<String>() {
@Override
public boolean visit(String classname)
{
// apply your filtering here
System.out.println(classname);
return true;
}
});
}
public interface Visitor<T>
{
public boolean visit(T t);
}
public static void findClasses(Visitor<String> visitor)
{
String classpath = System.getProperty("java.class.path");
String[] paths = classpath.split(System.getProperty("path.separator"));
for (String path : paths) {
File file = new File(path);
// Ignore JAR files, just go through directories on the classpath
if (file.isFile()) {
continue;
}
findFiles(file, file, visitor);
}
}
private static boolean findFiles(File root, File file,
Visitor<String> visitor)
{
if (file.isDirectory()) {
for (File child : file.listFiles()) {
if (!findFiles(root, child, visitor)) {
return false;
}
}
} else {
if (!visitor.visit(createRelativePath(root, file))) {
return false;
}
}
return true;
}
private static String createRelativePath(File root, File file)
{
StringBuffer sb = new StringBuffer();
sb.append(file.getName());
file = file.getParentFile();
while (file != null && !file.equals(root)) {
sb.insert(0, '/').insert(0, file.getName());
file = file.getParentFile();
}
return sb.toString();
}
}