2013-12-18 65 views
1

在我的屬性文件,我使用的系統變量是這樣的:評估物業價值

log4j.appender.RollingFile.File=${workspace.logs}/my.log 

我讀這樣的特性:

Properties p = new Properties(); 
p.load(new FileInputStream("logger.properties")); 
String label = (String) p.get("log4j.appender.RollingFile.File"); 
System.out.println(label); 

結果是:

${workspace.logs}/my.log 

如何用評估變量打印結果?例如

C:/logs/my.log

EDITED

我相信我能做到這一點的正則表達式 - 一些建議 - 如此完美的解決方案將如何替換$ {..}內容與System.property

+0

您必須自己編寫程序:查找名爲'workspace.logs'的屬性。 'java.util.Properties'沒有內置的評估'$ {...}'的能力。 – Jesper

回答

0

的Java沒有按不會自動執行此替換,它們只會被視爲字符串。您將不得不通過System.getenv()進行變量替換。

在此之前,您將不得不識別並使用正則表達式或其他機制取出變量。

Pattern p = Pattern.compile("\\$\\{([[email protected]]+)}"); 
Matcher m = p.matcher(label); 

if(m.find()) 
{ 
    String var = m.group(); 
    String envVar = var.replace("${","").replace("}",""); 
    label = label.replace(var,System.getenv(envVar)); 
} 

請注意,上面的代碼假設你只有一個變量在其他行明智的你將不得不使用while循環,而不是如果。還要注意,上面的代碼可能在語法上不正確,因爲我沒有任何java IDE。

+0

這是我的問題 - 你如何建議這樣做? – Dejell

+0

爲了您的方便,我已經添加了一個關於如何完成的示例代碼,但是您可能必須修復一些語法錯誤,但是您會得到一般想法。 – Buddha

+0

實際上最好在編譯後的字符串後添加* – Dejell

0

對於一個非常快速和骯髒的解決方案,你甚至可以使用替換循環,但是這不會佔用轉義佔位符分隔符(如果你有一天在你的值中提供了一個文字${foo}?)。我親手寫了一本簡單的Lexer/Parser夫婦來解決類似的問題,這不是一個非常複雜的任務。

但是我建議你在模板引擎中封裝第一個階段,以便與不同的實現一起玩。模板引擎必須被用來創建一箇中間的文字,你會再使用這樣的:

// Load the bindings from your configuration 
Map<String, Object> bindings = loadBindings(); 
Template tpl = new Template("log4j.properties"); 
tpl.bind(bindings); 
tpl.compile(); 

Properties resolvedConfiguration = new Properties(); 
Reader in = new StringReader(tpl.getText()); 
resolvedConfiguration.load(in); 

遺憾的是我沒能找到一個模板引擎有足夠的配置,以適應我的佔位符和變量分辨率需求,並且不得不寫我自己的,但是這是一項容易的任務(幾個小時的工作),因爲這種語言並不複雜。

1

首先,我們必須找到$ {}內部的內容。提取之後,更換了整個事情,從環境屬性的值(希望該workspace.logs是一個環境變量

)... 讓我們可以使用

System.getenv() 

和那麼我們可以用replace方法替換它。這應該在一個循環中完成的情況下有多個env_variable紀錄

Properties p = new Properties(); 
p.load(new FileInputStream("c:\\log4j.properties")); 
String label = (String) p.get("log4j.appender.RollingFile.File"); 
int firstIndex=label.indexOf("${"); 
int lastIndex=label.indexOf("}"); 
String tempKey =label.substring(firstIndex+2,lastIndex); 
String tempValue =System.getenv(tempKey); 
label=label.replaceFirst("\\$\\{((?s).*)\\}",tempValue); 
System.out.println(label); 

會給你輸出

c:/log/my.log 
+0

如果我有多個環境屬性,該怎麼辦? – Dejell

+0

@Dejel我已經在我的回答中提到了它...我只是給了你自己的部分.. :) –

0

如果你已經正確地設置系統變量,那麼你就能夠只使用

${sys:workspace.logs} 

獲得預期的輸出。

http://logging.apache.org/log4j/2.x/manual/lookups.html

可提到所以其實你需要寫log4j.appender.RollingFile.File = $ {SYS:workspace.logs} /my.log

和問題就解決了。