Как использовать загрузчик классов.getResources() правильно? [дубликат]


этот вопрос уже есть ответ здесь:

  • Как я могу перечислить файлы внутри файла JAR? 13 ответов

как я могу использовать ClassLoader.getResources() чтобы найти рекурсивно ресурсы из моего пути к классам?

например.

  • поиск всех ресурсов в META-INF каталог "": Представьте себе что-то вроде

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

    к сожалению, это не только получение URL именно этот "каталог".

  • все ресурсы с именем bla.xml (recursivly)

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

    но это возвращает пустой Enumeration.

и в качестве бонуса вопрос: каким образом ClassLoader.getResources() отличается от ClassLoader.getResource()?

5 71

5 ответов:

нет никакого способа рекурсивно искать через classpath. Вы должны знать полный путь к ресурсу, чтобы иметь возможность получить его таким образом. Ресурс может находиться в каталоге в файловой системе или в файле jar, поэтому это не так просто, как выполнение списка каталогов "путь к классам". Вам нужно будет указать полный путь к ресурсу, например '/com/mypath / bla.xml'.

для вашего второго вопроса getResource вернет первый ресурс, который соответствует имя ресурса. Порядок поиска пути к классу задается в javadoc для getResource.

Spring Framework имеет класс, который позволяет рекурсивно искать через classpath:

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

это самый простой wat, чтобы получить объект File, на который указывает определенный объект URL:

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

теперь, для ваших конкретных вопросов:

  • поиск всех ресурсов в META-INF "каталог":

вы действительно можете получить объект File, указывающий на этот 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();
}
  • все ресурсы с именем bla.XML (recursivly)

в этом случае, вам придется сделать какой-то пользовательский код. Вот фиктивный пример:

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

когда код будет запущен, вы получите все найденные ocurrences в foundFiles список.

вот код, основанный на ответе 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);
            }
        }
    }

Мральвассер, я бы дал вам подсказку, бросьте URL.getConnection() до JarURLConnection. Затем используйте JarURLConnection.getJarFile () и вуаля! У вас есть JarFile, и вы можете получить доступ к ресурсам внутри.

остальное я оставляю вам.

надеюсь, что это помогает!