11

我正在编写一个包含许多可保存设置的 java 应用程序。基本上我的配置结构是这样的:

配置
|_ 游戏 1
   |_ 游戏名称:等等……
   |_ 玩家姓名:alice
   |_ 玩家姓名:鲍勃
   |_ 其他设置...
|_ 游戏 2
   |_ 游戏名称:哈哈
   |_ 玩家姓名:alice
   |_ 玩家姓名:鲍勃
   |_ 其他设置...
|_ 游戏 n....

你明白了。我尝试使用 xml,但使用 dom4j 很痛苦,尤其是在不同和相同的父节点中有很多同名的子节点,我需要对它们进行大量更改。到目前为止,我发现最简单的方法是使用纯文本文件,例如

[游戏一]
游戏名称:呸呸呸
选手姓名:爱丽丝
选手姓名:鲍勃
...

[游戏 2]
...

但我觉得这是非常初级的。那么在Java中维护配置文件的最佳或标准做法是什么?

编辑:我希望解决方案是可移植的,例如将文件从一台计算机复制到另一台计算机不会破坏程序。(抱歉忘记提前提到这一点。)

4

4 回答 4

5

在 java 中存储设置/首选项的最佳方式是使用Preferences API

于 2013-07-11T12:12:37.060 回答
2

考虑使用YAML来定义您的配置,与 XML 相比,它的详细程度要低得多,例如:

games:
  - name: 'game 1'
    players: ['Bob', 'Alice']
    ...
  - name: 'game 2'
    players: ['Bob', 'Alice']
    ...

然后,您可以使用带有YAML 扩展的Jackson库与配置进行交互,例如解析配置:

File configFile = new File("...");
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
Configuration config = mapper.readValue(configFile, Configuration.class);
于 2013-07-11T13:22:39.157 回答
2

您应该使用自动编组器来编写您的 XML 文件。几年前,我使用CastorXML,但今天,可能有更现代的 API 用于此目的。

使用此 API,您基本上可以:

  • 将所有配置存储在一个简单的 POJO 中
  • 实例化一个 Marshaller
  • 调用 marshaller.write(MyConfig)

当你想加载你的配置时:

  • 实例化一个解组器
  • 调用 Marshaller.read(yourFile)

您可以在配置文件中描述 XML 映射或使用默认 Marshaller(1 个属性 ~ 1 个 XML 标记)

就是这么简单。

编辑:

此线程中搜索之后,JAXB 规范是在 CastorXML 首次发布之后出现的,而 Sun 的 JAXB 实现现在似乎是Java <-> XML映射的标准。

于 2013-07-11T12:08:15.083 回答
1

查看Apache Commons 配置

它为分层配置提供了良好的支持。

XMLConfiguration config = new XMLConfiguration("games.xml");
String gameName = config.getString("game1.name");
List<Object> playerNames = config.getList("game1.players.player.name");
// ...
config.setProperty("game1.name", "Space Invaders"); // update game name
config.addProperty("game1.players.player(-1).name", "ted"); // add new players
config.addProperty("game1.players.player(-1).name", "carol"); 
config.clearTree("game1.players.player(1)"); // remove a player

// Or with XPath 
config.setExpressionEngine(new XPathExpressionEngine());
config.addProperty("game1/players player/name", "ted"); 
config.addProperty("game1/players player/name", "carol"); 
config.clearTree("game1/players/player[2]");
于 2013-07-11T12:23:07.070 回答