简体   繁体   中英

getResources() return enumeration with only 1 object

I try to get the list of files from classpath (web-inf/classes/dir).

Enumeration<URL> en = getClass().getClassLoader().getResources("dir");

However, instead of elements in this folder, the only element is the folder itself. Is there a way I can get the list of files, or the only way is to access file one by one. Because when I try to refer to some file in the same folder, I can easily access its contents.

You can't browse a directory on the classpath recursively.

See this post: How to use ClassLoader.getResources() correctly?

If you know you're looking at a JAR file however, you might open it directly as an archive and browse the files.

Somebody came up with a useful answer for this question: Get all of the Classes in the Classpath

You could adapt this code to browse through all JAR files and directories on your classpath and apply some filter for your directory name yourself. The example will list all classes from the gnu.trove.* package:

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();
    }

}

Here is some code for ignoring JAR files and just going through the files on directories on your classpath:

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();
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM