【问题标题】:Get all images within directory - within jar file获取目录中的所有图像 - 在 jar 文件中
【发布时间】:2012-08-14 11:45:18
【问题描述】:

我的项目中有一个包含 238 张图像的文件夹。我希望能够找到目录中的所有图像。

我目前正在像这样访问所有这些图像:

File directory = new File(FileNameGuesser.class.getResource(DIRECTORY).getPath());
for (File file : directory.listFiles()) {
    // filter, process, etc.
}

这在 Eclipse 中运行良好。但是,当我导出到 jar 文件时,FileNameGuesser.class.getResource(DIRECTORY) 返回C:\Users\...\file.jar!\org\...(因为它是压缩的,我假设)并且方法中断。

我怎样才能做到这一点?

编辑:如果可能的话,我想在部署的 jar 中找到一个在 Eclipse中都有效的解决方案。

【问题讨论】:

  • @AndrewThompson 好吧,它可能被视为重复,但除了您的链接中提供的答案之外,还有其他答案。我提供了一个与这些不同的功能齐全的答案。
  • @maba ..就像您可能已就链接问题提供了答案一样。很多事情都是可能的。 :)
  • @AndrewThompson 嗯,是的,我可以有,但那会淹没在所有其他答案中,而且这个问题相当陈旧,受到的关注更少。

标签: java resources io classpath


【解决方案1】:

真的不可能以任何好的和干净的方式实现。

能够做到.getClass().getResources("/pictures/*.jpg")(或其他什么)会很好,但我们不能。

你能做的最好的就是稍微作弊。如果您知道存储图像的 jar 文件的名称,则可以使用 JarFileZipFile API 来获取列表:

ZipFile zipFile = null;
try {

    zipFile = new ZipFile(new File("...")); // Path to your Jar
    Enumeration<? extends ZipEntry> entries = zipFile.entries();
    while (entries.hasMoreElements()) {

        ZipEntry entry = entries.nextElement();

        // Here, I've basically looked for the "pictures" folder in the Zip
        // You will need to provide the appropriate value
        if (!entry.isDirectory() && entry.getName().startsWith("pictures")) {

            // Basically, from here you should have the full name of the
            // image.  You should be able to then construct a resource path
            // to the image to load it...

            // URL url = getClass().getResource("/" + entry.getName());
            System.out.println(entry.getName());

        }

    }

} catch (Exception exp) {

    exp.printStackTrace();

} finally {


    try {
        zipFile.close();
    } catch (Exception e) {
    }

}

如果您事先不知道它们的名称,更好的解决方案是不要将这些图像嵌入到您的 jar 中。

您的应用程序确实应该提前知道嵌入式资源的名称。

按照 AndrewThompson 的建议,您可以生成资源列表,并将其添加到您的 Jar 文件中。在运行时,您将加载此文件并有权访问所有资源。

【讨论】:

  • new ZipFile(new File("...")); 在小程序或 JWS 应用程序中不起作用。即使资源被缓存,URL 也将始终指向服务器。如果资源被缓存,它们通常是松散的文件(至少在 JWS 缓存中),而不是 Zip 或 Jar 风格的档案。请注意,可以为 URL 获取 ZipInputStream。有关详细信息,请参阅链接的“重复”接受的答案。
  • 这是有道理的。那么zipFile.entries() 会递归获取 zip/jar 中的所有文件和文件夹吗?
  • @AndrewThompson +1 以获得更多积分。我确实说过这是作弊,也许我应该说这是黑客攻击。最好将这些资源放在 Jar/Zip 之外
  • 大家,请查看 AndrewThompson 提供的链接。他使用 URL 和 ZipStream 的想法是使用文件引用的更好方法!
  • “如果可能的话,我想找到一个既能在在 Eclipse 中 也能在部署的 jar 中工作的解决方案。”我觉得最好通过使用构建工具来编译/jar/(sign/)运行代码并使用适合 Jar 的方法来解决。 -- 还有另一种获取内容列表的方法,但它也需要构建工具。也就是说,创建一个目标文件列表并将其放在 Jar 中的已知位置。在运行时从已知位置检索列表,读取列表。
【解决方案2】:

可以使用Spring提供的PathMatchingResourcePatternResolver

public class SpringResourceLoader {

    public static void main(String[] args) throws IOException {
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        // Ant-style path matching
        Resource[] resources = resolver.getResources("/pictures/**");

        for (Resource resource : resources) {
            System.out.println("resource = " + resource);
            InputStream is = resource.getInputStream();
            BufferedImage img =  ImageIO.read(is);
            System.out.println("img.getHeight() = " + img.getHeight());
            System.out.println("img.getWidth() = " + img.getWidth());
        }
    }
}

我没有对返回的 Resource 做任何花哨的事情,但你明白了。

将此添加到您的 maven 依赖项(如果使用 maven):

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.1.2.RELEASE</version>
</dependency>

这将直接在 Eclipse/NetBeans/IntelliJ 部署的 jar 中工作。

在 IntelliJ 中运行会得到以下输出:

resource = file [C:\Users\maba\Development\stackoverflow\Q12016222\target\classes\pictures\BMW-R1100S-2004-03.jpg]
img.getHeight() = 768
img.getWidth() = 1024

使用可执行 jar 从命令行运行会得到以下输出:

C:\Users\maba\Development\stackoverflow\Q12016222\target>java -jar Q12016222-1.0-SNAPSHOT.jar
resource = class path resource [pictures/BMW-R1100S-2004-03.jpg]
img.getHeight() = 768
img.getWidth() = 1024

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 2012-01-14
    • 2012-05-16
    • 1970-01-01
    相关资源
    最近更新 更多