Перенаправить System.out из каждого потока

1

Я создал swing ui и перенаправил System.out и System.err в текстовое поле с этим кодом

ConsoleOutputStream cos = new ConsoleOutputStream(textColor, printStream);
System.setOut( new PrintStream(cos, true) );

ConsoleOutputStream расширяет ByteArrayOutputStream, и пока ничего не выполняется в новых потоках, это работает так, как ожидалось.

Однако мое приложение выполняет сторонние файлы jar, которые, в свою очередь, создают новые потоки. Когда эти потоки печатаются на System.out, он печатается в терминале, который запускал мое приложение, а не в текстовом поле. Я просмотрел эту ссылку: http://maiaco.com/articles/java/threadOut.php, но я не уверен, что это применимо к моей проблеме, поскольку у меня нет никакого контроля над потоками. Насколько известно моему приложению, не создаются нити (кроме основного потока gui).

Есть ли способ перенаправить все System.out: s и System.err: s независимо от потоков? Если нет, могу ли я слушать вызовы в System.out, а затем распечатать их в текстовое поле? Могу ли я прослушивать терминал, чтобы я запустил приложение и перенаправил весь вывод из него в мое приложение?

  • 2
    System.out не является специфичным для потока. Проверьте, когда вы вызываете setOut относительно того, когда третья сторона lib читает System.out. Возможно, что он читает значение в и кэширует его сам.
  • 1
    Или, если сторонний файл JAR выполняется в своем собственном процессе, он не унаследует потоки вашей программы.
Теги:
multithreading
redirect
swing
system.out

1 ответ

4
Лучший ответ

System.out не зависит от потока. Есть две возможности:

  1. Библиотеки читают System.out прежде чем перенаправить его и кешировать значение. Исправление заключается в перенаправлении System.out перед вызовом кода сторонней библиотеки.

  2. Библиотеки не используют System.out. Для записи на консоль есть альтернативы, такие как создание new FileOutputStream(FileDescriptor.out) и запись на него. Или с помощью System.console().

    Если это происходит через один из известных API протоколирования, вы можете переопределить поведение, удалив обработчик журнала консоли по умолчанию и установив собственный. В противном случае его довольно сложно сделать. Вам нужно будет изучить библиотеки и их API, чтобы узнать, как это сделать. Каждая сложная библиотека предложит способ записи сообщений непосредственно на консоль, не предлагая альтернативы - это действительно плохой стиль программирования, особенно для библиотеки.

    Очень вероятно, что библиотеки, которые вы используете, используют API протоколирования.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню