.properties文件是否适合存储分层设置 – 对象?

我的任务是负责工作,需要持久的客户端设置。 这些设置由我正在实现的框架的C#版本中的XML文件表示,它表示具有最多六个级别的层次结构的对象。 此外,不同级别中的对象数有时是任意的,如ArrayList。 遗憾的是,对象序列化不是一种选择,因为需要能够直接编辑文件。 我不得不将这些设置的持久性实现为.properties文件,但我担心这是否是一个好主意。

据我所知,.properties文件只能以与HashMap相同的方式使用,只有字符串的键值配对。 复杂对象的表示似乎只能用长而复杂的关键字符串表示,它代表每个元素的整个“路径”,包括它可能在几个列表中的单个索引。

filters.filter3.traces.rule4.add1.value="8" 

我还没有找到任何可行的方法来在.properties文件中保留分层对象,但我也无法找到任何明确证据表明它不可能。

那么,.properties文件是否适合存储分层设置 – 对象? 或者我应该将我的属性实现为XML文件或JSON?

我会坚持使用XML文件。 没有什么比使用API​​框架的不同变体的不同格式更能激怒用户。

您可以使用Apache XMLBeans等库来简化读取和写入XML文件的过程,使用模式文件自动生成适当的Java类。

属性文件可用于存储分层数据,但手动编辑这些东西真的很痛苦,并且很容易引入错误。 有些人认为XML编辑也不是轻而易举,但至少存在编辑器可以在与XSD链接时更容易。

我总是发现这种存储分层配置数据的方式非常繁琐,但它很有可能。 例如,它(以前是?)是配置Log4j的最常用方式,但根据我的经验,越来越多的开发人员也在这里切换到XML。

我真的没有看到为此目的使用属性文件的意义。

你有一个log4jforms的完美例子:这里是属性样本。

 log4j.appender.R = org.apache.log4j.DailyRollingFileAppender log4j.appender.R.File = logs/bensApps.log log4j.appender.R.Append = true log4j.appender.R.DatePattern = '.'yyy-MM-dd log4j.appender.R.layout = org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n 

如果这些键中有层次结构,例如:

 Map root = new HashMap<>(); root.put("level1", "foobar"); root.put("level2", Collections.singletonMap("p", "foobar"); 

您可以将其翻译为:

 level1=foobar level2.p=foobar 

在阅读文件时,要分开. 进入子图:

 Map root = new HashMap<>(); Properties propz = new Properties(); // load from your file for (Map.Entry entry : propz.entrySet()) { String[] path = entry.getKey().split('\\.'); Map parent = root; int n = path.length - 1; for (int i = 0; i < n; ++i) { String p = path[i]; Object child = parent.get(p); if (null == child) { Map _p = new HashMap<>(); parent.put(p, _p); parent = _p; } else if (child instanceof Map) { parent = (Map) child; } else { // it is up to you to do something when the path extends beyond a "final" key } } parent.put(path[n], entry.getValue()); } 

然而,这是一个“重新发明轮子”模式,其他答案指出你可能比自己做更好的解决方案。 这个例子也向您展示了一种问题:

 p1=foobar p1.p2=foobar 

在机器生成的属性的情况下,这不会发生,并且exception可能是最佳答案。 但是在人类操纵属性的情况下,这可能有一些含义。

另外,由于Java 7附带了JAXB,您也可以使用完整的XML来完成,而无需额外的库。 并使用某种层次结构。

我认为你已经掌握了它的要点 – Java属性文件可以表达层次结构,但是很笨拙。

看看Typesafe Config库 ,这是Play Framework使用的库。 它的主要语言是HOCON(人为优化的配置符号),它非常适合表达层次属性。 该库还兼容属性文件和JSON,因此您可以轻松地同时支持所有这些语言。

在Java属性文件中,正如您所说,您只能使用虚线键

 abc = 42 

在HOCON中,您可以选择执行此操作或使用花括号嵌套部分。 因此,该示例可以通过以下任何方式表达:

 abc : 42 a { bc : 42 } ab { c : 42 } a { b { c : 42 } }