java - 捕获 Java 中特定线程的控制台输出

标签 java multithreading console

我意识到在 SO 上也有类似的问题,但它们并没有完全解决我的问题。

我想要一个方法,给定一个 Class 对象,将调用该类(如果存在)上的“main”方法,也就是说,public static void main 并捕获该 main 方法的控制台输出.执行调用的类是非守护线程。

我已经有了部分代码,但我不确定如何捕获控制台输出,最重要的是,如何只为 *this 特定线程捕获它。这是我到目前为止所拥有的:

public class Output extends Thread {
    private Class testClass;

    public Output(Class clazz) {
        this.testClass = clazz;
    }

    private Method getMainMethod(Class clazz) {
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            if (isMainMethod(method)) { 
                return method;
            }
        }

        return null;
    }

    private Boolean isMainMethod(Method method) {
        return (method.getName().equals("main") &&
                Modifier.isStatic(method.getModifiers()) &&
                method.getReturnType().equals(Void.class));
    }

    public void run() {
        Method mainMethod = null;

        if ((mainMethod = getMainMethod(this.testClass)) == null) {
            //if there's no static void main method, throw exception
            throw new YouFuckedItUpException();
        }

        mainMethod.invoke(this.testClass, new String[0]);

        return heresWhereImStuckIWantToCaptureTheConsoleOutputAndReturnIt();
    }
}

我所需要的只是一些代码,或者指向有关如何捕获被调用方法的 System.out 和 System.err 输出的答案的链接。如果有人能提供任何帮助,我们将不胜感激。

提前致谢!

编辑:这不仅仅用于测试,最终将投入生产。

编辑 2:这需要是线程安全的。多个 main 方法可能会同时被其他线程调用,我希望每个线程只捕获自己的特定输出。

最佳答案

使用System.setOut然后编写一个 printstream 的子类,它会覆盖所有打印/写入方法并记录来自您要监视的线程的数据。

伪代码:

public class HackedPrintStream extends PrintStream {
    private PrintStream originalStream;
    private HashMap<Thread, PrintStream> loggerStreams = new HashMap<Thread, PrintStream>();

    public HackedPrintStream(PrintStream originalStream) {
        this.originalStream = originalStream;
    }

    public synchronized void logForThread(Thread threadToLogFor, PrintStream streamToLogTo) {
        loggerStreams.put(threadToLogFor, streamToLogTo);
    }

    /** example overridden print method, you need to override all */
    public synchronized void println(String ln) {
        PrintStream logPS = loggerStreams.get(Thread.currentThread());
        if (logPS != null) { logPS.println(ln); }
        originalStream.println(ln);
    }
}

然后你可以创建和使用这个流

HackedPrintStream hps = new HackedPrintStream(System.out);
System.setOut(hps);

不过,我真的建议您努力寻找另一种解决方案,因为这不太好。

关于java - 捕获 Java 中特定线程的控制台输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/741775/

相关文章:

java - Java中unicode值的序列与正则表达式的匹配

java - 添加时间我不知道如何添加

c - pthread_cond_timedwait 立即返回

multithreading - windows phone 7中UI控件的线程亲和性

javascript - 类型错误 : Illegal Invocation on console. log.apply

c# - 控制台或图形游戏设计?

java - 如何在java中使用正则表达式分割字符串

java - 如何在Java中将int数组转换为base64字符串?

python - python线程可以访问命名空间中的变量吗?

c# - 在同一控制台中启动进程