Java 运行jar时的当前目录路径

Java 运行jar时的当前目录路径,java,netbeans,Java,Netbeans,我的程序通过从当前目录读取xml文件来读取配置数据: File fXmlFile = new File("configFile.xml"); 它在NetBeans IDE中运行良好。我已经建立了项目,并得到了jar文件。如果我在Windows10中双击它,它运行良好。如果我用鼠标右键点击jar打开文件,并且openwith->Java程序找不到配置文件。在这种情况下,我得到了一个例外: java.io.FileNotFoundException: C:\Windows\System32\con

我的程序通过从当前目录读取xml文件来读取配置数据:

File fXmlFile = new File("configFile.xml");
它在NetBeans IDE中运行良好。我已经建立了项目,并得到了jar文件。如果我在Windows10中双击它,它运行良好。如果我用鼠标右键点击jar打开文件,并且
openwith->Java
程序找不到配置文件。在这种情况下,我得到了一个例外:

java.io.FileNotFoundException: C:\Windows\System32\configFile.xml (The system cannot find the file specified)
为什么它只查看系统路径而不查看当前目录?在
openwith->Java
case中运行时,如何要求程序加载当前目录中的文件

Jar的清单文件:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.4
Created-By: 12.0.1+12 (Oracle Corporation)
Class-Path: lib/log4j-api-2.11.2.jar lib/log4j-core-2.11.2.jar lib/met
 ouia.jar lib/swt.jar
X-COMMENT: Main-Class will be added automatically by build
Main-Class: com.aaa.myprog.runMe 

正如我看到的,问题的出现是因为您需要知道在执行时如何解析相对路径,“当前目录”发生在这个执行上,所以请允许我解释一下

据我所知,“当前目录”也称为工作目录,它是在启动java应用程序时设置的,它假定值为,即您执行java命令以启动应用程序的目录

例如:

如果您打开一个命令终端,将自己放在目录
“C:\pepe”
中,然后从该目录执行命令来启动jar,例如:
java-jar“C:\path\to\my\app.jar”
,那么工作目录将是
“C:\pepe\”
在您的程序中,对相对路径的任何引用都将使用
前缀“c:\pepe\”
完成

然后将它们放入行
File fXmlFile=new File(“configFile.xml”)
将指示jvm在
“c:\pepe\configFile.xml”
中查看该文件,因为如我前面所述,相对路径
configFile.xml
将使用工作目录(在启动时设置)解析

记住java如何设置工作目录,以及如何使用工作目录作为前缀解析相对路径,从现在开始,帮助您解决任何引用问题

您可能会发现此链接很有用:用于调查netbeans启动java应用程序时设置的工作目录

运输署;博士:


“pepe”是西班牙语中的一个词,相当于英语中的“foo”:D,希望学习新东西!!:正如Victor已经指出的那样,当前目录依赖于用于启动JVM的命令,因此在运行时是动态的。相反,您需要一个依赖于jar文件本身位置的定位器,这意味着它在编译时是动态的,但在运行时是静态的

这里有不同的方法,所以让我简单介绍两种:

使用启动程序脚本
通过这种方式,您只需自己控制命令行,但您必须在计划使用程序的每个操作系统上都这样做。在Windows上,它可能如下所示:

app.bat:

cd %~dp0
java -jar app.jar
关于第一行的更多信息

使用系统类加载器
这是可行的,因为系统类加载器的源代码在编译时是动态的,但在运行时是静态的,所以这正是您所需要的。但是,它的缺点是您无法写入配置文件,因为您只能获得
InputStream

app.jar

try (InputStream fXml = ClassLoader.getSystemClassLoader().getResourceAsStream("configFile.xml")) {
    ...
}

还有一个完整的MCVE

ConfigFile.java:

public class ConfigFile {
    public static void main(String[] args) {
        try (final BufferedReader configFile = new BufferedReader(
            new InputStreamReader(ClassLoader.getSystemClassLoader()
                .getResourceAsStream("configFile.txt")))) {
            System.out.println(configFile.readLine());
        } catch (final IOException exc) {
            exc.printStackTrace();
        }
    }
}
ConfigFile.txt

你好,世界
MANIFEST.MF

清单版本:1.0
类路径:。
主类:prv.izruo.test.ConfigFile
命令行

P:\workspace\ConfigFile>dir部署
...
2019年5月2日20:43 1.434 configFile.jar
2019年5月2日20:43 11 configFile.txt
P:\workspace\ConfigFile>java-jar部署\ConfigFile.jar
你好,世界

阅读应用程序可能需要的
config.xml
和其他资产的最佳方法是将它们放入
src/main/resources
中,然后将它们作为类路径中的文件引用,如下所示:

mv configFile.xml/users/vico/my_program/src/main/resources
Java代码
/。。。
公共静态文件getResourceAsFile(字符串resourcePath){
试一试{
InputStream in=ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
if(in==null){
返回null;
}
File tempFile=File.createTempFile(String.valueOf(in.hashCode()),“.tmp”);
tempFile.deleteOnExit();
try(FileOutputStream out=newfileoutputstream(tempFile)){
//复制流
字节[]缓冲区=新字节[1024];
int字节读取;
while((bytesRead=in.read(buffer))!=-1){
out.write(缓冲区,0,字节读取);
}
}
返回临时文件;
}捕获(IOE异常){
e、 printStackTrace();
返回null;
}
}
文件fXmlFile=getResourceAsFile(“configFile.xml”);
// ...
(此代码借用自)


然后,您可以将您的jar移动到任何您想要的地方,甚至可以将其发送给您的用户,并且不再担心配置文件位于何处。

相对于您的jar文件,配置文件位于何处?jar和配置文件位于同一目录“如果您执行
c:\pepe\java-jar”c:\path\to\my\app.jar”
工作目录将是
“c:\pepe\”
“-这是不正确的。您可以使用
cd
将任何目录设置为当前工作目录,然后执行相同的命令。工作目录不是由执行程序的位置定义的,它是单个进程或父命令shell的属性。感谢您指出,据我所知,在没有任何其他配置的情况下,您的工作目录默认为执行命令的目录。如果有其他设置工作目录的方法,请告诉我们,请随意编辑我的帖子,以列举其他设置工作目录的方法。
cd C:\pepe
是如何更改工作目录的。啊,明白你的意思,请允许我修改我的post@VGRth