当我在IDE中运行应用程序时,使用..
(两个句点)可以轻松完成accessing the parent directory(相对于当前目录)。
这是一个简单的例子:
包结构
src
└───main
├───java
│ │ Main.java
│ │
│ └───controllers
│ Controller.java
│ InnerController.java
│
└───resources
└───fxml
inner-layout.fxml
layout.fxml
从Controller
内部,我试着说,"上升一级,然后去找fxml/inner-layout.fxml
"。
URL relativeResource = Controller.class.getResource("../fxml/inner-layout.fxml");
// Returns: "file:/C:/Users/BradTurek/IdeaProjects/Parent%20Directory%20Jar%20MCVE/build/resources/main/fxml/inner-layout.fxml"
这适用于文件系统。
但是,当我将应用程序部署为可执行.jar
文件时,..
不再被解释为"上一个目录"。我检查过:我可以仍然访问.jar
中的资源 - 除非我使用包含..
的路径。
似乎..
在处理.jar
内的路径时无法正常工作。
您可以自行下载并运行a full MCVE of the above example。
这个问题的答案在互联网上很容易 ,但它可能在那里。我的希望是,我已经清楚地提出了这个问题,以便让其他人轻易找到答案。
为什么会这样?
答案 0 :(得分:4)
首先,它是说方法Class.getResource(String)
没有指定任何支持处理" .."在路上。所以你的问题的答案可以在这里结束:"因为规范没有定义这种行为" 。
当从IDE内部启动应用程序时它起作用的原因是,在这种情况下,本地文件系统工具用于访问资源。这些能够解决" .."在你的道路上。
但是JAR文件本身不是文件系统 - 它只是一个压缩容器,以非定义的顺序保存所有.class文件和其他资源(请参阅JAR file specification - Oracle)。虽然它符合ZIP文件标准,其中包含一个目录列表,称为“中心目录”。 (参见ZIP (file format) - Wikipedia),在用于解析路径之前,必须首先使用此列表构建树状可导航路径结构。我假设由于性能和内存消耗的原因,没有通过类加载器加载类和其他资源。
但在你的情况下,根本没有理由使用相对路径,因此依赖路径解析。相反,您可以使用绝对路径。这听起来更糟糕,因为这样的绝对路径在文件系统方面并不是真正的绝对路径,但与类路径根目录相关的绝对路径!
所以这应该有效:
URL resource = Controller.class.getResource("/fxml/inner-layout.fxml");
无论是从文件系统,JAR文件还是从远程存储库服务器通过HTTP加载资源都无关紧要。