我的程序通过从当前目录阅读xml文件来读取配置数据:
File fXmlFile = new File("configFile.xml");
它在NetBeans IDE中运行良好。我有构建项目并获得jar文件。如果我在Windows 10中双击它,它运行良好。如果我通过右键单击jar打开文件,Open with -> Java
程序找不到配置文件。在这种情况下,我遇到了异常:
java.io.FileNotFoundException: C:\Windows\System32\configFile.xml (The system cannot find the file specified)
为什么它只看系统路径而不看当前目录?在Open with -> Java
的情况下运行时,如何让程序加载当前目录中的文件?
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
3条答案
按热度按时间zzlelutf1#
读取
config.xml
和应用可能需要的其他资产的最佳方法是将它们放入src/main/resources
中,然后在类路径中将它们作为文件引用,如下所示:shell
Java代码
(this代码借用自this stackoverflow answer)
然后,您可以将jar移动到任何您想要的地方,甚至将其发送给您的用户,而不必担心配置文件在哪里。
j1dl9f462#
正如维克托已经指出的,当前目录依赖于启动JVM的命令,因此在运行时是动态的,而需要一个依赖于jar文件本身位置的定位器,这意味着它在编译时是动态的,但在运行时是静态的。
这里有不同的方法,所以让我简短地介绍两种:
使用启动程序脚本
这样你就可以自己控制命令行了,但是你必须在你计划使用程序的每个操作系统上都这样做。在Windows上,它可能是这样的:
app.bat:
更多信息请参见第一行here。
使用系统类加载器
这是可行的,因为System ClassLoader的源代码在编译时是动态的,而在运行时是静态的,这正是您所需要的,但是,它也有缺点,您不能写入配置文件,因为您只能得到一个
InputStream
。app.jar
以及完整的MCVE。
ConfigFile.java:
ConfigFile.txt
MANIFEST.MF
命令行
eit6fx6z3#
正如我所看到的,这个问题的出现是因为您需要知道 * 相对路径是如何在执行时解析的 *,而"当前目录"发生在这个等式上,所以请允许我稍微解释一下。
据我所知,"当前目录"也称为工作目录,它是在您启动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如何设置工作目录以及 * 如何使用工作目录作为前缀解析相对路径 *,将帮助您从现在开始解决任何引用问题。
您可能会发现此链接很有用:How to get the current working directory in Java?,用于调查NetBeans(为我们)启动Java应用程序时设置的工作目录。