1

当一个方法生成对 STDERR 的写入时,有什么方法可以捕捉到吗?我正在尝试在每次 STDERR 写入时预先添加一些信息。

假设我们的方法是:

parser.thatGeneratesSTDERR();

它会产生类似的东西

第 37:29 行在字符“a”处没有可行的替代方案

我可以用一些可以捕获要写入的 stderr 的东西来包装它并预先附加一些信息,所以它看起来像这样:

文件:mybadfile.txt——第 37:29 行在字符“a”处没有可行的替代方案

我知道我可能可以深入研究编写 STDERR 的实际代码,但我真的不想这样做——我宁愿只在这个方法周围包装一些代码。

我应该注意,这种方法并不总是生成 STDERR——我试图捕捉它们的原因是它不应该生成任何 STDERR——但是因为它在很多文件(超过 40 个)上被调用,所以我永远不知道哪个文件正在生成错误消息——它需要很长时间才能找到。

更新 所以是的,我们可以更改我们的 STDERR - 我只是忘记了我需要在我的新 STDERR 中覆盖我的 println ......这是相关代码:

public static String errfile = "";

static {
  final PrintStream currentErr = System.err;
  PrintStream newErr = new PrintStream(currentErr)
  { 
    public void println(String string) {
      print("File: " + errfile + " --");
      print(string);
      super.println();
    }
  };

  System.setErr(newErr);
}

然后对于我正在测试的每个文件,我所要做的就是将 errfile 更改为文件名,并且我的输出结果符合预期......

多谢!

4

3 回答 3

1

听起来您可能想看看面向方面的编程(AOP)。使用 AOP,您可以为正在调用的解析器创建代理。在调用 thatGeneratesSTDERR() 方法之前,您可以让它调用您调用。从您的通话中,您可以输出您想要的信息。

请注意,可能需要阅读一些内容才能了解 AOP 的工作原理。

AspectJ - http://www.eclipse.org/aspectj/

AOP 联盟 - http://sourceforge.net/projects/aopalliance

于 2009-06-23T19:15:42.570 回答
1

鉴于 System.setErr 的工作原理,我不确定这是否可行。

我会创建一个新的类来扩展打印流并覆盖添加您的评论的方法。然后将错误流设置为新的打印流。不要从这个新类调用 System.err.printxxx。

前任...

class PrependPrintStream extends PrintStream {

PrependPrintStream(PrintStream ps, String pre){...}
...
public void print(boolean b) {
super.print(this.pre);
super.print(b);
}
...

我查看了 sun 的 PrintStream impl,它看起来像所有 printxxx 委托都写入(String),它是私有的而不是受保护的。我想你可以复制/粘贴代码。

编辑::

一个更好的解决方案是使用 Logging 而不是 System.err。这允许您关闭和打开您的语句,并允许您创建自定义错误处理程序。您的特定处理程序可以在打印到 System.err 之前将您希望的语句添加到字符串中。这还有一个优点,即只有使用您的特定记录器的语句才会有前置文本,而对 System.err 的其他调用则不会。

于 2009-06-23T19:26:21.207 回答
0

您可以使用System.setErr将 stderr 重定向到您自己的 PrintStream。

于 2009-06-23T19:22:21.510 回答