Java应用的配置文件

huangapple go评论72阅读模式
英文:

Config file for a Java Application

问题

我正在构建一个Java应用程序,打算将其打包成未来的Windows可执行文件。我的NetBeans项目结构可以在这里看到。
我目前正在使用getResourceAsStream()从config.properties中读取内容。我之前并不知道无法通过类似的方式将文件写入该文件。是否有人能够建议一种实现这一目标的方法,或者是否需要采取不同的解决方案来解决我的问题?谢谢。

英文:

I am building a Java Application with the intention of packaging it to be a windows executable in the future. My NetBeans project structure can be seen
here.
I am currently reading from config.properties using getResourceAsStream(). I was not aware that this file cannot be written to in a similar manner. Would anyone be able to advise a way to achieve this or is a different approach to my problem required? Thanks.

答案1

得分: 3

我认为你可以使用java.util.properties来解决你的问题;要写入属性,首先创建一个新的Properties对象,通过你的InputStreamload它们,使用诸如setProperty的方法添加到你的配置中,最后使用store将其写入。

示例:

File appConfig = new File("a_file");
FileInputStream propsInput = new FileInputStream("a_file");

Properties prop = new Properties();

prop.load(propsInput);

try (Writer inputStream = new FileWriter(appConfig)) {

   // 设置属性。
   prop.setProperty("A_PROP", "A_VALUE");

   // 将属性与标题注释一起存储在文件中。
   prop.store(inputStream, "INFORMATION!!!");

} catch (IOException ex) {
   ex.printStackTrace();
}
英文:

I think you can use java.util.properties to solve your problem; to write to your properties first create a new Properties object, load them via your InputStream, use methods such as setProperty to add to your configuration and finally use store to write to them.

Example:

File appConfig = new File("a_file");
FileInputStream propsInput = new FileInputStream("a_file");

Properties prop = new Properties();

prop.load(propsInput);

try (Writer inputStream = new FileWriter(appConfig)) {

   // Setting the properties.
   prop.setProperty("A_PROP", "A_VALUE");

   // Storing the properties in the file with a heading comment.
   prop.store(inputStream, "INFORMATION!!!");

} catch (IOException ex) {
   ex.printStackTrace();
}

答案2

得分: 0

没有直接的答案来回答如何外部化配置的问题 —— 这取决于应用程序以及部署的环境。

Java首选项API试图通过提供一个平台中立的首选项API来解决这个问题。在Linux上,数据实际上存储在$HOME/.java目录的子目录中的XML文件中,但是程序员不应该关心这些细节。使用这个API很方便,但不允许存储复杂的数据,并且不容易让程序员为应用程序提供从特定位置读取配置的方式。

除了使用首选项API,您还可以显式地读写文件。对于简单的“name=value”配置,您可以使用Properties对象,它有处理文件的方法。这种方法允许指定文件位置,但是控制文件位置需要对您可能支持的各种平台进行一些适应。

如果您的配置比“name=value”更复杂,您可以以您选择的格式读写它 —— JSON,YAML,XML等。所有这些文件格式在Java中都得到很好的支持。使用基于文本的格式允许用户使用其他工具编辑配置,如果他们愿意的话。

在实际应用中,我几乎总是将配置外部化为序列化的Java对象,存储在我控制的文件中。这允许配置具有任意复杂性,而无需额外的编码,因为您直接存储Java数据。要将程序结构化为可序列化的,需要一些工作,但从长远来看是值得的。不幸的是,这种方法不容易在程序外部轻松编辑配置。

如果您打算在容器中运行应用程序(如Docker等),则需要考虑完全不同的情况。您需要使用与容器平台兼容的外部化配置方法,简单地读写文件在这种环境中通常是不合适的。

如果您不确定如何处理配置,可以在实现您定义的接口的类中执行它。然后,如果以后改变主意,可以提供一个实现相同接口的不同类。

英文:

There's no straightforward answer to the question how to externalize configuration -- it depends on the application and the environment in which it will be deployed.

The Java preferences API is an attempt to get around this problem by providing a platform-neutral API for preferences. On Linux, the data is actually stored in an XML file in a subdirectory of $HOME/.java but, of course, the programmer isn't supposed to be concerned about this. Using this API is convenient, but doesn't allow complex data to be stored, and doesn't easily allow the programmer to provide the application with a way to read configuration from some specific place.

Rather than use the preferences API you can read/write files explicitly. For simple 'name=value' configuration, you can use a Properties object, which has methods for handling files. This method does allow a specific file location but, of course, controlling the file location does require some adaptation for the various platforms you might support.

If your configuration is more complex than 'name=value', you could read/write it in a format of your choice -- JSON, YAML, XML, etc. All these file formats are well-supported by Java. Using a text-based format allows users to edit the configuration using other tools, if they so wish.

In practice, I nearly always externalize configuration in serialized Java objects, into a file whose location I control. This allows configuration of arbitrary complexity without additional coding, since you're storing Java data directly. It takes a bit of work to structure a program to be serialized, but it's worth it in the long run. Unfortunately, this approach does not allow for easy editing of the configuration outside the program.

If you ever intend to run the application in a container (Docker, etc), then completely different considerations apply. You'll need to use a method of externalizing configuration that is compatible with the container platform -- simply reading and writing files is often inappropriate in such an environment.

If you're unsure how you want to handle configuration, do it in a class that implements an interface you define. Then, if you later change your mind, you can supply a different class that implements the same interface.

huangapple
  • 本文由 发表于 2020年10月11日 05:35:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/64298538.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定