我将我的应用设置存储在我在Ant和Java应用中使用的属性文件中。也许这不是很好的实践,但我觉得避免重复是非常方便的。该文件包含变量,如:
usefulstuff.dir = ${user.home}/usefulstuff
这样其他人就可以在* nix系统上运行该程序,只要他们的主目录中有有用的资料文件夹。
现在,令人着迷的是这个属性文件在 Ant (变量被解析为/home/username
)中运行良好,而当我直接在Java应用程序中加载相同的文件时,我得到一个包含${user.home}/usefulstuff
的字符串,这确实不是很有用。
我在Ant中使用此代码加载道具:
<loadproperties srcFile="myProps.properties"/>
在Java应用程序中:
FileInputStream ins = new FileInputStream(propFilePath);
myProps.load(ins);
ins.close();
我错过了什么吗?也许有更好的方法在Java应用程序中加载属性而不是load()
?
答案 0 :(得分:6)
我认为这在Ant中起作用并不特别“迷人” - Ant is deliberately written to do so:
属性是键值对,其中Apache Ant尝试在运行时将
${key}
扩展为值。
和
Ant提供对所有系统属性的访问,就像使用
<property>
任务定义它们一样。例如,$ {os.name}扩展为操作系统的名称。
如果你想要相同的行为,你需要实现相同的逻辑。您可以直接使用Ant中的类,如果他们按照您的意愿行事 - 并且您很乐意发送相关的二进制文件(并遵守许可证)。
否则,您可能希望使用正则表达式来查找所有匹配项 - 或者(可能更简单)迭代所有系统属性并对它们进行简单替换。
答案 1 :(得分:2)
正如乔恩所说,自己编写财产处理应该是直截了当的。例如:
import java.util.*;
public class PropertiesTest
{
public static void main(String[] args)
{
Properties props = new Properties();
props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
System.out.println("BEFORE:");
printProperties(props);
resolveSystemProperties(props);
System.out.println("\n\nAFTER:");
printProperties(props);
}
static void resolveSystemProperties(Properties props)
{
Map<String, String> sysProps = readSystemProperties();
Set<String> sysPropRefs = sysProps.keySet();
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
for (String ref : sysPropRefs)
{
if (value.contains(ref))
{
value = value.replace(ref, sysProps.get(ref));
}
}
props.setProperty(name, value);
}
}
static Map<String, String> readSystemProperties()
{
Properties props = System.getProperties();
Map<String, String> propsMap =
new HashMap<String, String>(props.size());
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
propsMap.put("${" + name + "}", props.getProperty(name));
}
return propsMap;
}
static void printProperties(Properties props)
{
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
System.out.println(name + " => " + value);
}
}
}