我正在寻找一种方法来从给定的类路径目录中获取所有资源名称的列表,类似于方法 List; getResourceNames(字符串目录名称)
。
例如,给定一个包含文件 a.html
、b.html
、c.html< 的类路径目录 x/y/z
/code> 和子目录 d
、getResourceNames("x/y/z")
应返回包含以下字符串的 List
:['a.html', 'b.html', 'c.html', 'd']
。
它应该适用于文件系统和 jar 中的资源。
我知道我可以使用 File
、JarFile
和 URL
编写快速片段,但我不想重新发明轮子。我的问题是,考虑到现有的公共可用库,实现 getResourceNames 的最快方法是什么? Spring 和 Apache Commons 堆栈都是可行的。
I am looking for a way to get a list of all resource names from a given classpath directory, something like a method List<String> getResourceNames (String directoryName)
.
For example, given a classpath directory x/y/z
containing files a.html
, b.html
, c.html
and a subdirectory d
, getResourceNames("x/y/z")
should return a List<String>
containing the following strings:['a.html', 'b.html', 'c.html', 'd']
.
It should work both for resources in filesystem and jars.
I know that I can write a quick snippet with File
s, JarFile
s and URL
s, but I do not want to reinvent the wheel. My question is, given existing publicly available libraries, what is the quickest way to implement getResourceNames
? Spring and Apache Commons stacks are both feasible.
发布评论
评论(18)
自定义扫描仪
实施您自己的扫描仪。例如:(
评论中提到了该解决方案的局限性< /a>)
Spring 框架
使用
PathMatchingResourcePatternResolver
。Ronmamo 反思
对于巨大的 CLASSPATH 值,其他技术在运行时可能会很慢。更快的解决方案是使用 ronmamo 的 Reflections API,它在编译时预编译搜索。
Custom Scanner
Implement your own scanner. For example:
(limitations of this solution are mentioned in the comments)
Spring Framework
Use
PathMatchingResourcePatternResolver
from Spring Framework.Ronmamo Reflections
The other techniques might be slow at runtime for huge CLASSPATH values. A faster solution is to use ronmamo's Reflections API, which precompiles the search at compile time.
这是代码
来源:forums.devx.com/showthread.php?t=153784
如果您使用 Spring 请查看 PathMatchingResourcePatternResolver
Here is the code
Source: forums.devx.com/showthread.php?t=153784
If you are using Spring Have a look at PathMatchingResourcePatternResolver
使用反射。
当提出这个问题时,这个答案是有效的。随后,我认为 Reflections 项目的维护并没有太一致。我将答案留在这里,但我现在会亲自查看其他一些答案,例如使用 classgraph< 的答案/a>.
原始答案:
使用 Reflections。
获取类路径上的所有内容:
另一个示例 - 从 some.package 获取扩展名为 .csv 的所有文件:
请注意:(更新)
这个答案写于 2015 年,可能使用了 Reflections 0.9.10。随后,我尝试了更高版本的 Reflections 库,并努力让这个答案发挥作用。我还努力从他们自己的文档中获取示例来工作...就我个人而言,我不确定该项目的维护者在做什么...也许这是我的一个错误。
Reflections 项目已从 Google Code Archive 版本 0.9.9-RC1,显而易见 [此处]。该项目目前在 github [此处] 上进行维护。
Using Reflections.
This answer was valid when this questions was asked. Subsequently I don't think the Reflections project has been maintained too consistently. I am leaving the answer here, but I would personally look at some of the other answers now for example the ones using classgraph.
Original answer:
Using Reflections.
Get everything on the classpath:
Another example - get all files with extension .csv from some.package:
Please note: (update)
This answer was written in 2015 and probably used Reflections 0.9.10. Subsequently I've tried the later versions of the Reflections library and struggled getting this answer to work. I also struggled to get examples from their own documentation to work... Personally I'm not sure what the maintainers of the project is doing... Maybe it's an error on my part.
The Reflections project was migrated from the Google Code Archive at version 0.9.9-RC1 as is evident [here]. The project is currently being maintained on github [here].
因此,就 PathMatchingResourcePatternResolver 而言,这就是代码中所需要的:
So in terms of the PathMatchingResourcePatternResolver this is what is needed in the code:
目前列出类路径中所有资源的最强大的机制是 将此模式与 ClassGraph 结合使用,因为它可以处理最广泛的可能一系列类路径规范机制,包括新的 JPMS 模块系统。 (我是 ClassGraph 的作者。)
The most robust mechanism for listing all resources in the classpath is currently to use this pattern with ClassGraph, because it handles the widest possible array of classpath specification mechanisms, including the new JPMS module system. (I am the author of ClassGraph.)
如果您使用 apache commonsIO,您可以用于文件系统(可选地使用扩展过滤器):
以及资源/类路径:
如果您不知道“directoy/”是否在文件系统中或在资源中,您可以
添加或
在调用之前 并结合使用两者......
If you use apache commonsIO you can use for the filesystem (optionally with extension filter):
and for resources/classpath:
If you don't know if "directoy/" is in the filesystem or in resources you may add a
or
before the calls and use both in combination...
Spring 框架
的PathMatchingResourcePatternResolver
在以下方面确实很棒:Maven 依赖项:
The
Spring framework
'sPathMatchingResourcePatternResolver
is really awesome for these things:Maven dependency:
这应该可行(如果弹簧不是一个选项):
This should work (if spring is not an option):
我的方式,没有 Spring,在单元测试期间使用:
My way, no Spring, used during a unit test:
有了Spring,这很容易。无论是文件、文件夹,甚至多个文件,都有机会通过注入来完成。
此示例演示了位于
x/y/z
文件夹中的多个文件的注入。它确实适用于文件系统和 JAR 中的资源。
With Spring it's easy. Be it a file, or folder, or even multiple files, there are chances, you can do it via injection.
This example demonstrates the injection of multiple files located in
x/y/z
folder.It does work for resources in the filesystem as well as in JARs.
path-matching-resource-pattern-resolver
我将 Spring Framework 的 PathMatchingResourcePatternResolver 提取到一个独立的库中,供那些不能或不想导入整个 Spring Framework 库的人使用。
GitHub
https://github.com/SecretX33/path-matching-resource-pattern -resolver
添加依赖
Maven
Gradle
Gradle (KTS)
使用示例
查找单个资源
查找多个资源
path-matching-resource-pattern-resolver
I extracted Spring Framework's
PathMatchingResourcePatternResolver
into a standalone library for those that can't or don't want to import the whole Spring Framework library.GitHub
https://github.com/SecretX33/path-matching-resource-pattern-resolver
Add the dependency
Maven
Gradle
Gradle (KTS)
Usage example
Find a single resource
Find multiple resources
我认为您可以利用 [Zip 文件系统提供程序][1] 来实现此目的。使用 FileSystems.newFileSystem 时,您似乎可以将该 ZIP 中的对象视为“常规”文件。
在上面的链接文档中:
[Java 11 states][5] 中
jdk.zipfs
模块的文档:这是我使用您的示例资源制作的一个示例。请注意,
.zip
是.jar
,但您可以调整代码以使用类路径资源:Setup
Java
输出
I think you can leverage the [Zip File System Provider][1] to achieve this. When using
FileSystems.newFileSystem
it looks like you can treat the objects in that ZIP as a "regular" file.In the linked documentation above:
The documentation for the
jdk.zipfs
module in [Java 11 states][5]:Here is a contrived example I did using your example resources. Note that a
.zip
is a.jar
, but you could adapt your code to instead use classpath resources:Setup
Java
Output
结合了 Rob 的响应。
Used a combination of Rob's response.
对于根目录:
For root directory:
如您所见,这非常简单。当你的 jar 在服务器上运行时,它可以在运行时运行。
As you see it's very simple. And it works in runtime, when your jar was run on the server.
尽管我将资源放入资源文件夹并遵循上述答案,但这两个答案都不适合我。真正的伎俩是:
Neither of answers worked for me even though I had my resources put in resources folders and followed the above answers. What did make a trick was:
使用他的 Luke Hutchinsons 答案rel="nofollow noreferrer">ClassGraph 库,我几乎不费吹灰之力就能轻松获取资源文件夹中所有文件的列表。
假设在您的资源文件夹中,有一个名为
MyImages
的文件夹。获取该文件夹中所有文件的 URL 列表是多么容易:然后您只需执行以下操作:
然后可以将 URL 加载到流中或使用 Apache 的 FileUtils 将文件复制到其他位置,如下所示:
我认为 ClassGraph 是一个非常漂亮的库,可以使这样的任务变得非常简单且易于理解。
Expanding on Luke Hutchinsons answer above, using his ClassGraph library, I was able to easily get a list of all files in a Resource folder with almost no effort at all.
Let's say that in your resource folder, you have a folder called
MyImages
. This is how easy it is to get a URL list of all the files in that folder:Then you simply do this:
The URLs can then be loaded into streams or use Apache's FileUtils to copy the files somewhere else like this:
I think ClassGraph is a pretty slick library for making tasks like this very simple and easy to comprehend.
根据上面 @rob 的信息,我创建了要发布到公共领域的实现:
虽然我不希望
getResourcesAsStream
在目录上像这样工作,但它确实如此并且有效出色地。Based on @rob 's information above, I created the implementation which I am releasing to the public domain:
While I would not have expected
getResourcesAsStream
to work like that on a directory, it really does and it works well.