我有一个JavaFX应用程序,我使用antBuild打包它来构建单个安装程序.exe文件,我的应用程序有一些配置文件放在项目的根目录这样我从项目的根目录加载它们为了它们可以放在.jar文件旁边并且可以改变:
try {
File base = null;
try {
base = new File(MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI())
.getParentFile();
} catch (URISyntaxException e) {
System.exit(0);
}
try {
File configFile = new File(base, "config.properties");
}
所以在打包应用程序之后,即使我手动将文件放在带有jar文件的同一个地方,应用程序也无法识别它们并导致错误。
那么存储和存储某种配置文件的正确方法是什么,以及如何将它们添加到安装程序以在安装过程中将其放置到正确的位置?
答案 0 :(得分:2)
如果您的应用程序捆绑为jar文件,则MainApp.class.getProtectionDomain().getCodeSource().getLocation().toURI()
将返回jar:
方案URI。 constructor for File
taking a URI
假设它获得file:
方案URI,这就是您在此处收到错误的原因。 (基本上,如果您的应用程序捆绑为jar文件,资源 config.properties
根本不是文件,它是存档文件中的条目。)基本上没有(可靠的)更新捆绑应用程序的jar文件内容的方法。
我通常采用的方法是将默认配置文件捆绑到jar文件中,并在用户文件系统上定义用于存储可编辑配置文件的路径。通常这将与用户的主目录相关:
Path configLocation = Paths.get(System.getProperty("user.home"), ".applicationName", "config.properties");
或类似的东西。
然后在启动时你可以这样做:
if (! Files.exists(configLocation)) {
// create directory if needed
if (! Files.exists(configLocation.getParent())) {
Files.createDirectory(configLocation.getParent());
}
// extract default config from jar and copy to config location:
try (
BufferedReader in = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/config.properties")));
BufferedWriter out = Files.newBufferedWriter(configLocation);) {
in.lines().forEach(line -> {
out.append(line);
out.newLine();
});
} catch (IOException exc) {
// handle exception, e.g. log and warn user config could not be created
}
}
Properties config = new Properties();
try (BufferedReader in = Files.newBufferedReader(configLocation)) {
config.load(in);
} catch (IOException exc) {
// handle exception...
}
因此,这将检查配置文件是否已存在。如果没有,它将从jar文件中提取默认配置,并将其内容复制到定义的位置。然后它从定义的位置加载配置。因此,用户第一次运行应用程序时,它使用默认配置。之后,用户可以编辑配置文件,然后使用编辑后的版本。您当然可以根据需要创建用于修改内容的UI。这样做的一个好处是,如果用户做某事使配置不可读,他们可以简单地将其删除,并且将再次使用默认设置。
显然,这可以更好地防范异常(例如,由于某种原因目录是不可写的处理情况,使配置文件位置可由用户定义等),但这是我使用的基本结构在这些情况下。