应用程序配置文件
好的,所以我不想在这里展开一场圣战,但我们正在努力巩固处理应用程序配置文件的方式,我们正在努力决定采用哪种最佳方法。目前,我们分发的每个应用程序都使用其自己的临时配置文件,无论是属性文件(ini样式),XML还是JSON(目前仅在内部使用!)。
目前,我们的大多数代码都是Java,因此我们一直在研究Apache Commons Config,但发现它很冗长。我们也研究了XMLBeans,但似乎无所适从。我也觉得好像正在将XML推向一种格式,但是我的客户和同事对于尝试其他方法感到不安。我可以从客户的角度理解它,每个人都听说过XML,但是到最后,难道不应该使用正确的工具来完成这项工作吗?
如今,人们在生产系统中使用什么格式和库,还有其他人试图避免使用尖括号税吗?
编辑:确实需要跨平台解决方案:Linux,Windows,Solaris等,用于与配置文件交互的库的选择与格式的选择一样重要。
解决方案
回答
我们在哪个平台上工作?我建议尝试使用首选/通用方法。
- MacOSX-复制者
- Win32-注册表(或者自从我开发注册表以来,这里有一个新的注册表)
- Linux / Unix-〜/ .apprc(也许是名称值)
回答
据我所知,如果我们使用的是.NET,则Windows注册表不再是存储配置的首选方法,现在大多数应用程序都使用System.Configuration [1、2]。由于这也是基于XML的,因此似乎一切都朝着使用XML进行配置的方向发展。
如果我们想跨平台使用,我会说使用某种文本文件是最好的选择。至于所述文件的格式,我们可能要考虑是否有人要操纵它。由于文件的可见结构,因此XML似乎比INI文件更易于手动操作。
至于尖括号税,我不用太担心它了,因为XML库负责抽象它。唯一需要考虑的时间是,如果我们只有很少的存储空间可以使用并且每个字节都计数。
[1] System.Configuration命名空间http://msdn.microsoft.com/zh-cn/library/system.configuration.aspx
[2]在.NET中使用应用程序配置文件http://www.developer.com/net/net/article.php/3396111
回答
在没有发起新的神圣战争的情况下,"尖括号税"职位的情绪是我主要不同意杰夫的一个领域。 XML没什么问题,它是人类可读的(与YAML或者JSON或者INI文件一样),但请记住它的意图是由机器读取。大多数语言/框架组合都免费提供某种XML解析器,这使XML成为不错的选择。
另外,如果我们使用的是像Visual Studio这样的优秀IDE,并且XML附带了一个架构,则可以将该架构提供给VS并神奇地获得智能感知(例如,可以为NHibernate获得一个)。
基本上,我们需要考虑一次要在生产中一次接触这些文件的频率,也许不是那么频繁。
这仍然对我说了所有有关XML的信息,以及为什么它仍然是配置文件的有效选择(来自Tim Bray):
"如果我们想提供通用数据,使接收者可能想做不可预料的怪异和疯狂的事情,或者我们想对i18n真正地偏执和挑剔,或者我们发送的内容更像是文档而不是结构,或者如果数据顺序很重要,或者数据可能寿命很长(例如几秒钟),那么XML是必经之路。
在我看来,XML和XPath的组合在需要可扩展的数据格式上达到了最佳的位置。也就是说,编写XML处理代码非常容易,在消息格式发生更改时,如果不涉及我们关心的部分,这些操作就不会失败。"
回答
我们使用属性文件是因为Java本身支持它们。几个月前,我看到SpringSource Application Platform使用JSON来配置他们的服务器,这看起来非常有趣。我比较了各种配置表示法,得出的结论是XML目前似乎是最合适的。它具有良好的工具支持,并且与平台无关。
回答
我们正在使用ini样式的配置文件。我们使用Nini库来管理它们。 Nini使它非常易于使用。 Nini原本是用于.NET,但已使用Mono移植到其他平台。
回答
回复:epatel的评论
我认为最初的问题是询问管理员将要执行的应用程序配置,而不仅仅是存储用户首选项。我们为用户偏好提供的建议似乎比应用程序配置更多,并且通常不是用户可以直接处理的(应用程序应在UI中提供配置选项,然后更新文件)。我真的希望我们永远不要让用户必须查看/编辑注册表。 :)
至于实际的问题,我想说XML可能还可以,因为很多人会习惯于使用XML进行配置。只要我们以一种易于使用的方式来组织配置值,那么"尖括号税"应该不会太糟。
回答
XML XML XML XML。我们在这里谈论配置文件。如果我们不打算在性能要求很高的情况下序列化对象,则没有"尖括号税"。
除了机器可读之外,配置文件还必须是人类可读的和人类可以理解的。 XML是两者之间的良好折衷。
如果商店中有人担心这种新型XML技术,那对我们来说很不好。
回答
@赫姆斯
我真正的意思是坚持建议的方法,即软件应为任何给定平台存储配置值。
然后,我们通常会得到建议/应该/可以修改的方法。类似于程序中的配置菜单或者"系统偏好"应用程序中的配置面板(用于系统服务软件)。不允许最终用户直接通过RegEdit或者NotePad对其进行修改...
为什么?
- 最终用户(=客户)习惯于他们的平台
- 备份系统可以更好地保存"安全设置"等
@九边
关于"库的选择",请尝试链接(静态链接)任何选定的库,以降低在最终用户计算机上陷入版本冲突之战的风险。
回答
YAML,原因很简单,与XML相比,它使可读性更高的配置文件成为可能。
XML:
<user id="babooey" on="cpu1"> <firstname>Bob</firstname> <lastname>Abooey</lastname> <department>adv</department> <cell>555-1212</cell> <address password="xxxx">[email protected]</address> <address password="xxxx">[email protected]</address> </user>
YAML:
babooey: computer : cpu1 firstname: Bob lastname: Abooey cell: 555-1212 addresses: - address: [email protected] password: xxxx - address: [email protected] password: xxxx
示例摘自以下页面:http://www.kuro5hin.org/story/2004/10/29/14225/062
回答
XML,JSON,INI。
他们都有自己的长处和短处。
在应用程序上下文中,我觉得抽象层很重要。
如果我们可以选择一种结构化数据的方式,该方式在人类可读性与我们要如何访问/提取代码中的数据之间找到一个很好的中间立场,那么我们就是无所不能。
我们通常在工作的地方使用XML,我不能真正相信一个配置文件在第一次读取或者写入之后作为对象加载到缓存中,然后从程序的其余部分抽象出来,实际上就是对CPU和磁盘空间都没有影响。
只要我们正确构造文件,它也很容易阅读。
并且所有平台上的所有语言都通过一些非常通用的库支持XML。
回答
第一:这是一个很大的辩论问题,而不是快速的问答。
我现在最喜欢的是简单地包含Lua,因为
- 我可以允许width = height *(1 + 1/3)之类的东西
- 我可以提供自定义功能
- 我可以禁止其他任何事情。 (例如,在Python中(包括泡菜)是不可能的。)
- 无论如何,我可能想要在项目中其他地方使用脚本语言。
如果有大量数据,另一种选择是使用sqlite3,因为它们是正确的声明
- 小的。
- 快速地。
- 可靠的。
选择任意三个。
我要添加以下内容:
- 备份很轻松。 (只需复制db文件。)
- 更容易切换到另一个数据库,ODBC,等等。 (比从丑文件)
但是,这又是一个更大的问题。对此的"大"答案可能涉及某种特征矩阵或者情况列表,例如:
数据量或者运行时间短
- 对于大量数据,我们可能需要高效的存储,例如数据库。
- 对于短期运行(通常),我们可能需要不需要大量解析的内容,请考虑可以直接映射的内容。
配置与什么有关?
- 它应该集中管理吗?注册表/ gconf /远程数据库?
- 用户可以有几个不同的配置文件吗?
复杂
- 只有几个固定值吗?考虑使用YAML。
- 数据是嵌套的还是以某种方式依赖的? (这是很有趣的地方。)
- 允许某种形式的脚本编写是否是理想的功能?
- 模板可以视为一种配置文件。
回答
在这里可能有点切线,但是我的看法是,应在应用程序首次启动时将配置文件读取到键值字典/哈希表中,并始终通过此对象进行访问以提高速度。通常,键/值表以字符串到字符串的形式开始,但是对象中的辅助函数会执行诸如DateTime GetConfigDate(string key)等的操作。
回答
帅哥
但是,应用程序配置并不总是仅键/值对。看一下类似于tomcat配置的监听端口。这是一个例子:
<Connector port="80" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" /> <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
我们可以有任意数量的连接器。在文件中定义更多,并且存在更多连接器。不要再定义了,也就不存在了。没有简单的旧键/值对可以做到这一点(恕我直言)。
如果应用程序配置很简单,那么将诸如INI文件之类的简单内容读入字典中就可以了。但是对于诸如服务器配置之类的更复杂的东西,INI文件将很难维护,而诸如XML或者YAML之类的更具结构性的东西则更好。这完全取决于问题集。
回答
如果配置文件是一次写入,启动时只读,并且数据是一堆名称值对,那么最好的选择是开发人员可以首先使用的名称。
如果数据有点复杂(例如嵌套),那么使用YAML,XML或者SQLite可能会更好。
如果我们需要嵌套数据和/或者需要在启动后查询配置数据的功能,请使用XML或者SQLite。两者都具有用于结构化/嵌套数据的相当不错的查询语言(XPATH和SQL)。
如果配置数据是高度规范化的(例如第五范式),那么使用SQLite更好,因为SQL更适合处理高度规范化的数据。
如果计划在程序运行期间写入配置数据集,那么最好使用SQLite。例如,如果我们要从另一台计算机下载配置数据,或者要根据将来在程序执行中收集的数据来决定将来的程序执行决策。 SQLite实现了一个非常健壮的数据存储引擎,当由于断电或者由于错误而导致程序处于不一致状态的情况下,很难破坏数据存储引擎。数据损坏会导致高昂的现场支持成本,并且SQLite的性能将比任何本地解决方案甚至是围绕XML或者YAML的流行库都要好得多。
查看我的页面以获取有关SQLite的更多信息。