【问题标题】:How to redirect output from Groovy script?如何重定向 Groovy 脚本的输出?
【发布时间】:2009-10-07 13:33:00
【问题描述】:

我想知道是否有任何方法可以更改我从 Java 代码执行的 groovy 脚本的默认输出 (System.out)。

这是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?

【问题讨论】:

    标签: java groovy


    【解决方案1】:

    使用SystemOutputInterceptor 类。您可以在脚本评估之前开始拦截输出并在之后停止。

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

    【讨论】:

      【解决方案2】:

      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);
      }
      

      cmets之后

      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!"
      

      【讨论】:

      • 这可行,但我想将 any 输出重定向到标准输出。尤其是通过我们 println() 等内置函数。
      • 关于是对的。解决方案是将输出包装到 java.io.PrintStream 中并作为“out”属性传递给 shell!
      • 耶!,我的第一个青铜徽章!很高兴它解决了!你是如何包装输出的?
      • 恭喜!只需使用 new PrintStream(output) 并作为“out”属性传递给绑定。
      • 真的吗? binding.setProperty 接受一个 OutputStream 并以某种方式工作而无需调用 .write??
      【解决方案3】:

      使用 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'")
      

      【讨论】:

        【解决方案4】:

        我怀疑您可以通过覆盖 GroovyShell 元类中的 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!
        

        【讨论】:

          【解决方案5】:

          System.setOut() 正是您所需要的。

          【讨论】:

          • 恐怕 System.setOut 太重了 :) 它会更改整个 JVM 的全局输出,这不是我想做的事情 :)
          猜你喜欢
          • 1970-01-01
          • 2010-12-25
          • 2016-10-29
          • 1970-01-01
          • 1970-01-01
          • 2018-08-12
          • 1970-01-01
          • 2010-09-27
          • 2014-09-01
          相关资源
          最近更新 更多