简体   繁体   English

如何在类路径中找到具有指定名称的所有资源?

[英]How to locate all resources in classpath with a specified name?

I want to list all files with a specific name in the class path.我想在 class 路径中列出所有具有特定名称的文件。 I am expecting multiple occurrences, hence Class.getResource(String) will not work.我预计会出现多次,因此Class.getResource(String)将不起作用。

Basically I have to identify all files with a specific name (ex: xyz.properties) anywhere in the class path and then read the metadata in them cumulatively.基本上,我必须在 class 路径中的任何位置识别所有具有特定名称的文件(例如:xyz.properties),然后累积读取其中的元数据。

I want something of the effect Collection<URL> Class.getResources(String) but could not find anything similar.我想要一些效果Collection<URL> Class.getResources(String)但找不到类似的东西。

PS: I don't have the luxury of using any third party libraries, hence in need of a home grown solution. PS:我没有使用任何第三方库的奢侈,因此需要一个本土解决方案。

You can use Enumeration getResources(String name) on the class loader to achieve the same. 您可以在类加载器上使用Enumeration getResources(String name)来实现相同的功能。

For example: 例如:

Enumeration<URL> enumer = Thread.currentThread().getContextClassLoader().getResources("/Path/To/xyz.properties");
while (enumer.hasMoreElements()) {
    System.out.print(enumer.nextElement());
}

What I do is I read java source files from classpath and process them using ClassLoader . 我所做的是从classpath读取java源文件并使用ClassLoader处理它们。 I am using follwing code : 我正在使用以下代码:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

assert (classLoader != null);

// pkgName = "com.comp.pkg"
String path = pkgName.replace('.', '/');

// resources will contain all java files and sub-packages
Enumeration<URL> resources = classLoader.getResources(path);

 if(resources.hasMoreElements()) {
        URL resource = resources.nextElement();     
        File directory = new File(resource.getFile());
        // .. process file, check this directory for properties files
 }

Hope this helps you. 希望这对你有所帮助。

The existing answers that propose using ClassLoader.getResources(String) only work if the "name" in question is the full path of the resource.建议使用ClassLoader.getResources(String)的现有答案仅在所讨论的“名称”是资源的完整路径时才有效。 As the methods's javadoc states, " The name of a resource is a / -separated path name that identifies the resource. " It's unfortunate and misleading that the parameter is called "name" instead of "path."正如方法的 javadoc 所述,“资源的名称是标识资源的/分隔的路径名。 ”不幸的是,参数被称为“名称”而不是“路径”是令人误解的。

For those who, like me, are really looking for all resources with a given (simple) name - without knowing the full path of the resource - the current answers won't work.对于那些像我一样真正在寻找具有给定(简单)名称的所有资源的人 - 不知道资源的完整路径 - 当前的答案将不起作用。 @NandkumarTekale's code example states " resources will contain all java files and sub-packages " in the comments, but unfortunately that is not true. @NandkumarTekale 的代码示例在评论中声明“资源将包含所有 java 文件和子包”,但不幸的是,这不是真的。 Nor does it make any difference to use ClassLoader.findResources(String) (which is indeed protected in the ClassLoader class itself, but pulled into the public API by concrete subclasses like URLClassLoader , which in turn serves as the base class for most commonly used class loaders). Nor does it make any difference to use ClassLoader.findResources(String) (which is indeed protected in the ClassLoader class itself, but pulled into the public API by concrete subclasses like URLClassLoader , which in turn serves as the base class for most commonly used class装载机)。

The most straightforward solution that I could find uses the ClassGraph library:我能找到的最直接的解决方案是使用ClassGraph库:

try (ScanResult result = new ClassGraph().acceptClasspathElementsContainingResourcePath("*/html5.dtd").scan())
{
    System.err.println(result.getResourcesWithLeafName("html5.dtd").getURLs());
}

Sadly, this clashes with the OP's request for a solution without the use of third-party libraries.可悲的是,这与 OP 对不使用第三方库的解决方案的要求相冲突。 However, ClassGraph's source code is available on GitHub and can be used as an inspiration for a "home grown" solution.然而,ClassGraph 的源代码可在 GitHub 上获得,并可用作“本土”解决方案的灵感。 In broad strokes, one would have to find the class loader's base URLs (eg, using URLClassLoader.getURLs() ) and then write URL-specific code for searching the contents of each URL (eg, if it's a jar:file: ... URL, load the JAR and iterate over its contents, or if it's a file: ... URL use java.io.File to explore the folder contents). In broad strokes, one would have to find the class loader's base URLs (eg, using URLClassLoader.getURLs() ) and then write URL-specific code for searching the contents of each URL (eg, if it's a jar:file: .. . URL, load the JAR and iterate over its contents, or if it's a file: ... URL use java.io.File to explore the folder contents). There are a lot of special cases to consider, though (eg, OSGi class loaders), and a truly general solution would probably replicate a fair amount of what ClassGraph does under the hood.不过,有很多特殊情况需要考虑(例如,OSGi class 加载程序),一个真正通用的解决方案可能会复制相当多的 ClassGraph 在后台所做的工作。 If it is valid to assume that the resources will, for example, always be packaged in a JAR (or always as plain files in the file system), a more tailored solution could be created for just those cases.例如,如果假设资源将始终打包在 JAR 中(或始终作为文件系统中的普通文件)是有效的,则可以针对这些情况创建更定制的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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