【问题标题】:How to get resources path within a jar如何在jar中获取资源路径
【发布时间】:2012-05-13 05:38:59
【问题描述】:

我知道有很多类似的问题,但都没有成功。我可能遗漏了一些非常基本的东西。 我在应用程序 jar 文件中的 ressources 包中有 html 文件,我需要检索它们的路径来读取和更新它们。这是我的代码:

URL url  = ClassLoader.class.getResource("/com/lamalva/ressources/test.html");
System.out.println(url);          
java.awt.Desktop.getDesktop().browse(java.net.URI.create(url.toString()));

当我从 NetBeans IDE 运行此代码时,输​​出为: 文件:/Users/Philippe/NetBeansProjects/Test/build/classes/com/lamalva/ressources/SatelliteQuotaMonitor.html 并且 html 文件按预期在浏览器中打开,但是当我从 OSX 终端运行 jar 文件时,输出为: jar:file:/Users/Philippe/.Trash/Test/Test.jar!/com/lamalva/ressources/SatelliteQuotaMonitor.html 并且没有打开html文件。 无论我做什么,我都无法获得正确的路径。我一直都有“Test.jar!”在中间。 我将非常感谢您的帮助

【问题讨论】:

  • 为什么您的 JAR 文件会从您的 OSX 垃圾箱中执行?无论如何,我相当肯定您的默认浏览器不知道如何从 JAR 文件中检索 HTML 资源。
  • 不知道为什么jar文件是在垃圾箱外执行的。我遇到的问题没有简单的答案。我会将我的文件移出 jar 并将它们包含在 zip 文件中,这很容易并且应该可以工作。

标签: java macos resources jar


【解决方案1】:

单行答案是-

字符串路径 = this.getClass().getClassLoader().getResource().toExternalForm()。

基本上 getResource 方法给出了 URL。从此 URL 中,您可以通过调用 toExternalForm() 来提取路径。

参考:https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String)https://docs.oracle.com/javase/7/docs/api/java/net/URL.html#toExternalForm()

【讨论】:

  • 似乎可以在我的 IDE 中工作,但不能来自单独的 jar 文件本身。
【解决方案2】:

需要读取和更新jar文件中的资源吗?

您可以从输入流中读取内容 - 如果资源与类文件位于同一包中,则使用相对路径。

InputStream in = this.getClass().getResourceAsStream("/class/path/to/file");

要编写,您可能需要读入现有 jar 的内容,修改您想要的部分,然后使用 JarInputStream 和 JarOutputStream 写出更新的内容。

【讨论】:

  • 我的资源是 html 文件,我需要更新并在默认浏览器中打开。我不需要在应用程序中阅读它们,但我需要它们的路径才能在浏览器中打开它们。 html文件存储在资源中,因为它们需要资源/脚本中的javascripts
  • Java 中的 URL 不一定是 Web 浏览器可以理解的 URL。您需要将 jar 文件提取到临时位置,因为浏览器将无法显示 jar 中的文件。看看 java.util.jar.JarFile - 你需要遍历 entries() 方法并提取内容。
【解决方案3】:

要在默认平台 Web 浏览器中从类路径打开资源,您有两种选择。提取所述资源并将其复制到文件系统上的临时位置并传递文件:url。另一个可能更好的选择是运行嵌入式 Web 服务器(例如 Jetty)并直接从您的类路径提供资源。

【讨论】:

    【解决方案4】:

    带有!解压子协议的URL不能在普通浏览器中使用。就像ssh:(终端访问)或smtp:/mailto:(电子邮件)一样。此外,“file:..../my.jar!...”是普通 URL 的一个无法使用的扩展。

    有有限的 HTML 支持的 JTextPane/JEditorPane。还有一些java浏览器项目。

    也许可以使用嵌入 java Jetty Web 服务器。

    【讨论】:

      【解决方案5】:

      如果你想要一个 jar 中的资源,你需要使用多个 ClassLoader。这个片段也适用于 AppServers。

      在本例中,我从sqlite-jdbc-3.7.2.jar 读取位于org.sqlite 包中的文件。

      public class Main {
      
      private static InputStream getResourceAsStream(String resource) throws FileNotFoundException {
          String stripped = resource.startsWith("/") ? resource.substring(1) : resource;
          InputStream stream = null;
          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          if (classLoader != null) {
              stream = classLoader.getResourceAsStream(stripped);
          }
          if (stream == null) {
              stream = MyClass.class.getResourceAsStream(resource);
          }
          if (stream == null) {
              stream = MyClass.class.getClassLoader().getResourceAsStream(stripped);
          }
          if (stream == null) {
              throw new FileNotFoundException("File not found: " + resource);
          }
          return stream;
      }
      
      public static void main(String[] args) throws FileNotFoundException {
          // Read file from JAR sqlite-jdbc-3.7.2.jar
          Scanner sc = new Scanner(getResourceAsStream("org/sqlite/NativeDB.c"));
          while(sc.hasNextLine()) {
              System.out.println(sc.nextLine());
          }
      }
      

      }

      更多详情请阅读Java Classloader

      如果你想更新内容,可以Jar Inspector帮助你。

      【讨论】:

        猜你喜欢
        • 2020-12-09
        • 1970-01-01
        • 2010-10-30
        • 2014-07-04
        • 1970-01-01
        • 2021-12-21
        • 2023-03-23
        • 2021-04-24
        • 2019-11-27
        相关资源
        最近更新 更多