Как правильно использовать ClassLoader.getResources()?
Как я могу использовать ClassLoader.getResources()
для поиска рекурсивных ресурсов из моего пути к классам?
например.
-
найти все ресурсы в каталоге META-INF
":
Представьте себе что-то вроде
getClass().getClassLoader().getResources("META-INF")
К сожалению, это возвращает только URL
в этот "каталог".
-
все ресурсы с именем bla.xml
(рекурсивно)
getClass().getClassLoader().getResources("bla.xml")
Но это возвращает пустой Enumeration
.
И как бонусный вопрос: как ClassLoader.getResources()
отличается от ClassLoader.getResource()
?
Ответы
Ответ 1
Невозможно рекурсивно искать путь к классам. Вы должны знать полный путь к ресурсу, чтобы иметь возможность получить его таким образом. Ресурс может находиться в каталоге в файловой системе или в файле jar, поэтому это не так просто, как выполнение списка каталогов "путь к классам". Вам необходимо будет указать полный путь ресурса, например. '/com/mypath/bla.xml'.
Для вашего второго вопроса getResource вернет первый ресурс, соответствующий данному имени ресурса. Порядок поиска пути к классу приведен в javadoc для getResource.
Ответ 2
Spring Framework имеет класс, который позволяет рекурсивно искать путь к классам:
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
resolver.getResources("classpath*:some/package/name/**/*.xml");
Ответ 3
Это самый простой ват, чтобы получить объект 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);
Когда код запускается, вы получите все найденные осколки в списке foundFiles
.
Ответ 4
Вот код, основанный на ответе 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);
}
}
}
Ответ 5
MRalwasser, я бы дал вам подсказку, отбросив URL.getConnection()
до JarURLConnection
.
Затем используйте JarURLConnection.getJarFile() и voila! У вас есть JarFile, и вы свободны в доступе к ресурсам внутри.
Остальное я оставляю вам.
Надеюсь, это поможет!