【问题标题】:Java: Program stdout and stderr to some sort of handlerJava:将 stdout 和 stderr 编程到某种处理程序
【发布时间】:2010-11-25 02:48:42
【问题描述】:

有没有办法逐行捕获我的Java程序的stdout和stderror?

可能类似于使用 addHandler 将处理程序添加到 Logger 实例的方式。

编辑:我不想替换默认处理程序——我仍然需要在命令行上显示输出。

【问题讨论】:

  • 要求的原因是什么?如果是用于日志记录或调试,您应该考虑使用日志记录框架而不是 stderr 和 stdout。如果您在 *nix 系统上,您可以将 stdout 和 stderr 重定向到一个文件并尾随文件...
  • 我正在编写一个流式 API,您可以在其中获取程序的控制台输出。因此,进入控制台的任何内容也可以视为 http 流。

标签: java stdout handler stderr


【解决方案1】:

通过使用System.setOut()System.setErr(),您可以将标准输出和错误流设置为任何PrintStream,并捕获所有内容。

补充: 我不知道是否有任何优雅的方法可以做到这一点,但一种方法是:
1. 保存默认输出流
PrintStream defaultOut = System.out;
(不过,System.getOut() 会很有趣)
2. 将 System.out 重定向到您想要的打印流(例如任何文件)
3. 而不是使用 System.out.println() 使用您的打印功能,它执行以下操作:
打印(对象 o){
defaultOut.println(o);//假设defaultOut在这个函数中是可见的
System.out.println(o); }

【讨论】:

  • 我不想替换 PrintStreams,因为我仍然需要将输出转到命令行。
【解决方案2】:

System.setOutSystem.setErr 方法允许您更改 System.outSystem.err 变量引用的 PrintStream 对象。您可以使用它们将默认的 PrintStream 对象替换为捕获输出的对象,或者用它做任何您想做的事情。

跟进

我不想替换 PrintStreams,因为我仍然需要将输出转到命令行。

您的代码可以解决这个问题:

  1. 创建OutputStream 的子类,将所有输出写入另一个OutputStream 实例,并捕获输出。使“其他”实例成为构造函数参数。
  2. 获取System.outSystem.err的当前值。
  3. 两次实例化您的子类,分别使用System.outSystem.err 值作为构造函数参数。
  4. 将这两个实例包装为PrintStream 实例。
  5. 调用System.setOutSystem.setErrSystem.outSystem.err 替换为PrintStream 实例。

【讨论】:

  • 请记住,这将重定向 System.out 和 System.err 流,但不会重定向 JVM 直接打印的任何内容,例如当您执行在其上“kill -3”以转储线程和锁定信息。
  • 我不想替换 PrintStreams,因为我仍然需要将输出转到命令行。
  • @Paul Tomblin - 这是真的。不幸的是,除了破解 JVM 代码库或从另一个 JVM 启动 JVM 之外,您无能为力。
  • 有趣。我实现它的方式是扩展ByteArrayOutputStream,覆盖flush,然后使用new PrintStream(new HandleStdOut())。有什么区别吗?
【解决方案3】:

Message Console 允许您在文本窗格中显示输出并将其显示在命令行上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 2012-07-14
    • 2014-07-22
    • 2016-09-04
    相关资源
    最近更新 更多