web-dev-qa-db-fra.com

Comment utiliser ClassLoader.getResources () correctement?

Comment utiliser ClassLoader.getResources() pour rechercher des ressources récursives dans mon classpath?

Par exemple.

  • recherche de toutes les ressources dans le "répertoire" _META-INF_: Imaginez quelque chose comme

    getClass().getClassLoader().getResources("META-INF")

    Malheureusement, ceci ne récupère qu'un URL dans exactement ce "répertoire".

  • toutes les ressources nommées _bla.xml_ (récursivement)

    getClass().getClassLoader().getResources("bla.xml")

    Mais ceci retourne un Enumeration vide.

Et comme question supplémentaire: en quoi ClassLoader.getResources() diffère-t-il de ClassLoader.getResource()?

76
MRalwasser

Il n'y a aucun moyen de rechercher récursivement dans le chemin de classe. Vous devez connaître le chemin complet d'une ressource pour pouvoir la récupérer de cette manière. La ressource peut se trouver dans un répertoire du système de fichiers ou dans un fichier jar. Il ne suffit donc pas de répertorier le "chemin de classe" dans le répertoire. Vous devrez fournir le chemin complet de la ressource, par exemple "/com/mypath/bla.xml".

Pour votre deuxième question, getResource renverra la première ressource qui correspond au nom de ressource donné. L'ordre dans lequel le chemin de classe est recherché est donné dans le javadoc de getResource.

19
krock

Le framework Spring a une classe qui permet de rechercher récursivement dans le classpath:

PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
resolver.getResources("classpath*:some/package/name/**/*.xml");
34
rec

C'est le wat le plus simple pour obtenir l'objet File vers lequel un certain objet URL pointe vers:

File file=new File(url.toURI());

Maintenant, pour vos questions concrètes:

  • trouver toutes les ressources dans le "répertoire" META-INF:

Vous pouvez en effet obtenir l'objet File pointant vers cette URL

Enumeration<URL> en=getClass().getClassLoader().getResources("META-INF");
if (en.hasMoreElements()) {
    URL metaInf=en.nextElement();
    File fileMetaInf=new File(metaInf.toURI());

    File[] files=fileMetaInf.listFiles();
    //or 
    String[] filenames=fileMetaInf.list();
}
  • toutes les ressources nommées bla.xml (récursivement)

Dans ce cas, vous devrez créer du code personnalisé. Voici un exemple factice:

final List<File> foundFiles=new ArrayList<File>();

FileFilter customFilter=new FileFilter() {
    @Override
    public boolean accept(File pathname) {

        if(pathname.isDirectory()) {
            pathname.listFiles(this);
        }
        if(pathname.getName().endsWith("bla.xml")) {
            foundFiles.add(pathname);
            return true;
        }
        return false;
    }

};      
//rootFolder here represents a File Object pointing the root forlder of your search 
rootFolder.listFiles(customFilter);

Lorsque le code est exécuté, vous obtenez toutes les occurrences trouvées dans la liste foundFiles.

19
Tomas Narros

Voici le code basé sur la réponse de bestsss:

    Enumeration<URL> en = getClass().getClassLoader().getResources(
            "META-INF");
    List<String> profiles = new ArrayList<>();
    if (en.hasMoreElements()) {
        URL url = en.nextElement();
        JarURLConnection urlcon = (JarURLConnection) (url.openConnection());
        try (JarFile jar = urlcon.getJarFile();) {
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements()) {
                String entry = entries.nextElement().getName();
                System.out.println(entry);
            }
        }
    }
9
Mark Butler

MRalwasser, je vous donnerais un indice, transtorez la URL.getConnection() en JarURLConnection. Ensuite, utilisez JarURLConnection.getJarFile () et le tour est joué! Vous avez le JarFile et vous êtes libre d'accéder aux ressources à l'intérieur.

Le reste je vous laisse.

J'espère que cela t'aides!

5
bestsss