如何在Java中加载和解析(ant风格)的属性文件?

huangapple go评论73阅读模式
英文:

How to load and parse (ant style) properties file in Java?

问题

如何在Java中将属性文件加载到Property对象中并解析属性值(`${x}`会像ant属性一样被替换)?例如使用以下属性文件

foo=1
bar=${foo}.0

我需要将`bar`属性获取为`1.0`,而不是`${foo}.0`。有没有简单的方法来实现这个

编辑
Alex的解决方案适用于简单的情况在我的情况下我不得不解决另一个问题导致了这个问题[按顺序从Java属性文件中提取值][1]

加载和解析属性的示例代码如下
```java
import java.util.*;
import java.io.*;
import org.apache.commons.text.StringSubstitutor;

public class Prop {
	
    Properties parsedProperties = null;

	public static Properties parseProperties(String filename) {
		// 内部辅助类用于保持属性的顺序:
		class LinkedProperties extends Properties {

			private static final long serialVersionUID = 1L;
			private final HashSet<Object> keys = new LinkedHashSet<Object>();

		    public LinkedProperties() {
		    }

		    public Iterable<Object> orderedKeys() {
		        return Collections.list(keys());
		    }

		    public Enumeration<Object> keys() {
		        return Collections.<Object>enumeration(keys);
		    }

		    public Object put(Object key, Object value) {
		        keys.add(key);
		        return super.put(key, value);
		    }
		}
		
    	LinkedProperties result = new LinkedProperties();
    	try (InputStream input = new FileInputStream(filename)) {

            result.load(input);

            @SuppressWarnings("unchecked")
            StringSubstitutor sub = new StringSubstitutor((Map) result);
            
            for (Object k : result.orderedKeys()) {
            	result.setProperty((String)k, sub.replace(result.getProperty((String)k)));
            }
        } catch (IOException ex) { ex.printStackTrace(); }

        return ((Properties)result);
    }

    public static void main(String[] args) {
    	Prop app = new Prop();
    	
	    // 测试 - 写入示例属性文件:
    	try {
	    	PrintWriter writer = new PrintWriter(new FileWriter("config.properties"));
	        writer.println("foo=1");
	        writer.println("bar=1.${foo}");
	        writer.println("baz=${bar}.0");
	        writer.println("xxx=V.${baz}");
            writer.close();
	    } catch (IOException ex) { ex.printStackTrace(); }
	    
    	// 读取并解析属性:
	    app.parsedProperties = parseProperties("config.properties");

	    // 调试打印:
        for (Object k : app.parsedProperties.keySet()) {
        	System.out.println((String)k + " = " + app.parsedProperties.getProperty((String)k));
        }
	}
}

<details>
<summary>英文:</summary>
How to load property file into Property object in Java and get property values parsed (`${x}` gets replaced as it is done for ant properties)? For example using this property file:

foo=1
bar=${foo}.0

I need to get `bar` property as `1.0` instead `${foo}.0`. Is there a easy way for this?
EDIT:
Alex&#39;s solution works for simple scenarios. In my case I had to solve another issue leading to this question: [Pulling values from a Java Properties file in order?][1]. 
Resulting sample code for loading and parsing properties:

import java.util.;
import java.io.
;
import org.apache.commons.text.StringSubstitutor;

public class Prop {

Properties          parsedProperties   = null;
public static Properties parseProperties(String filename) {
// inner helper class keeping order of properties:
class LinkedProperties extends Properties {
private static final long serialVersionUID = 1L;
private final HashSet&lt;Object&gt; keys = new LinkedHashSet&lt;Object&gt;();
public LinkedProperties() {
}
public Iterable&lt;Object&gt; orderedKeys() {
return Collections.list(keys());
}
public Enumeration&lt;Object&gt; keys() {
return Collections.&lt;Object&gt;enumeration(keys);
}
public Object put(Object key, Object value) {
keys.add(key);
return super.put(key, value);
}
}
LinkedProperties result = new LinkedProperties();
try (InputStream input  = new FileInputStream(filename)) {
result.load(input);
@SuppressWarnings(&quot;unchecked&quot;)
StringSubstitutor sub = new StringSubstitutor((Map) result);
for (Object k : result.orderedKeys()) {
result.setProperty((String)k, sub.replace(result.getProperty((String)k)));
}
} catch (IOException ex) { ex.printStackTrace(); }
return ((Properties)result);
}
public static void main(String[] args) {
Prop app = new Prop();
// test - write sample properties file:
try {
PrintWriter writer = new PrintWriter(new FileWriter(&quot;config.properties&quot;));
writer.println(&quot;foo=1&quot;);
writer.println(&quot;bar=1.${foo}&quot;);
writer.println(&quot;baz=${bar}.0&quot;);
writer.println(&quot;xxx=V.${baz}&quot;);
writer.close();
} catch (IOException ex) { ex.printStackTrace(); }
// read and parse properties:
app.parsedProperties = parseProperties(&quot;config.properties&quot;);
// debug print:
for (Object k : app.parsedProperties.keySet()) {
System.out.println((String)k + &quot; = &quot; + app.parsedProperties.getProperty((String)k));
}
}

}


[1]: https://stackoverflow.com/questions/1312383/pulling-values-from-a-java-properties-file-in-order
</details>
# 答案1
**得分**: 3
```java
// 导入必要的类和包
import org.apache.commons.text.StringSubstitutor;
// 初始化示例属性
Properties p = new Properties();
p.setProperty("foo", "${baz}.${baz}");
p.setProperty("bar", "${foo}.0");
p.setProperty("baz", "5");
Properties resolved = parseProperties(p);
System.out.println("resolved: " + resolved);
/////
public static Properties parseProperties(Properties orig) {
Properties result = new Properties();
StringSubstitutor sub = new StringSubstitutor((Map) orig);
orig.entrySet().forEach(e -> result.put(e.getKey(), sub.replace(e.getValue())));
return result;
}

输出:

resolved: {bar=5.5.0, foo=5.5, baz=5}

注意:上述内容是您提供的代码的翻译,可能会因为格式限制而略有不同。

英文:

You may use StringSubstitutor from Apache Commons Text, its Maven dependency is pretty modest (~200K):

&lt;!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text --&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.commons&lt;/groupId&gt;
&lt;artifactId&gt;commons-text&lt;/artifactId&gt;
&lt;version&gt;1.8&lt;/version&gt;
&lt;/dependency&gt;

Code example:

// init sample properties
Properties p = new Properties();
p.setProperty(&quot;foo&quot;, &quot;${baz}.${baz}&quot;);
p.setProperty(&quot;bar&quot;, &quot;${foo}.0&quot;);
p.setProperty(&quot;baz&quot;, &quot;5&quot;);
Properties resolved = parseProperties(p);
System.out.println(&quot;resolved: &quot; + resolved);
/////
public static Properties parseProperties(Properties orig) {
Properties result = new Properties();
StringSubstitutor sub = new StringSubstitutor((Map) orig);
orig.entrySet().forEach(e -&gt; result.put(e.getKey(), sub.replace(e.getValue())));
return result;
}

Output:

resolved: {bar=5.5.0, foo=5.5, baz=5}

huangapple
  • 本文由 发表于 2020年5月4日 19:10:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/61590835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定