4

我将我的应用程序设置存储在我在 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()吗?

4

2 回答 2

6

我认为这在 Ant 中起作用并不是特别“令人着迷” - Ant 是故意编写的

属性是 Apache Ant 尝试${key}在运行时扩展为值的键值对。

Ant 提供对所有系统属性的访问,就好像它们是使用<property>任务定义的一样。例如,${os.name} 扩展为操作系统的名称。

如果您想要相同的行为,则需要实现相同的逻辑。您可以直接使用 Ant 中的类,前提是它们执行您想要的操作 - 并且您愿意发布相关的二进制文件(并遵守许可证)。

否则,您可能希望使用正则表达式来查找所有匹配项 - 或者(可能更简单)迭代所有系统属性并对其进行简单替换。

于 2011-10-14T19:08:02.810 回答
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);
        }
    }
}
于 2011-10-14T20:03:10.933 回答