2009-10-07 100 views
13

不知有什麼辦法,我可以改變我是從我的Java代碼執行Groovy腳本的默認輸出(System.out的)。如何重定向Groovy腳本的輸出?

下面是Java代碼:

public void exec(File file, OutputStream output) throws Exception { 
    GroovyShell shell = new GroovyShell(); 
    shell.evaluate(file); 
} 

和樣品Groovy腳本:

def name='World' 
println "Hello $name!" 

目前該方法的執行,評估寫入腳本的 「Hello World!」到控制檯(System.out)。如何將輸出重定向到作爲參數傳遞的OutputStream?

回答

16

試試這個使用Binding

public void exec(File file, OutputStream output) throws Exception { 
    Binding binding = new Binding() 
    binding.setProperty("out", output) 
    GroovyShell shell = new GroovyShell(binding); 
    shell.evaluate(file); 
} 

後評論

public void exec(File file, OutputStream output) throws Exception { 
    Binding binding = new Binding() 
    binding.setProperty("out", new PrintStream(output)) 
    GroovyShell shell = new GroovyShell(binding); 
    shell.evaluate(file); 
} 

Groovy腳本

def name='World' 
out << "Hello $name!" 
+2

這將工作,但我想重定向*任何輸出寫入標準輸出。特別是通過內置函數println()。 – 2009-10-07 13:48:53

+0

你是* *正確的。解決方法是將輸出包裝到java.io.PrintStream中,並作爲「out」屬性傳遞給shell! – 2009-10-07 14:21:42

+0

yay!,我的第一個銅牌徽章! 快樂的工作吧!你是如何包裝輸出的? – jjchiw 2009-10-07 14:40:31

2

我懷疑你可以通過覆蓋在GroovyShell的metaClass上的println方法做到這一點相當不錯。在Groovy控制檯以下工作:

StringBuilder b = new StringBuilder() 

this.metaClass.println = { 
    b.append(it) 
    System.out.println it 
} 

println "Hello, world!" 
System.out.println b.toString() 

輸出:

Hello, world! 
Hello, world! 
2

使用SystemOutputInterceptor類。您可以在腳本評估之前開始攔截輸出,然後停止。

def output = ""; 
def interceptor = new SystemOutputInterceptor({ output += it; false}); 
interceptor.start() 
println("Hello") 
interceptor.stop() 
2

如何使用javax.script.ScriptEngine?您可以指定其作者。

ScriptEngine engine = new ScriptEngineManager().getEngineByName("Groovy"); 
PrintWriter writer = new PrintWriter(new StringWriter()); 
engine.getContext().setWriter(writer); 
engine.getContext().setErrorWriter(writer); 
engine.eval("println 'HELLO'")