Как получить вывод консоли Java на веб-страницу? [Дубликат]

Эта «ошибка» дала мне много часов работы сверхурочных! Но я начинаю видеть его потенциальное использование (но мне хотелось бы, чтобы это было во время выполнения, все еще)

Я дам вам то, что я вижу в качестве полезного примера.

def example(errors=[]):
    # statements
    # Something went wrong
    mistake = True
    if mistake:
        tryToFixIt(errors)
        # Didn't work.. let's try again
        tryToFixItAnotherway(errors)
        # This time it worked
    return errors

def tryToFixIt(err):
    err.append('Attempt to fix it')

def tryToFixItAnotherway(err):
    err.append('Attempt to fix it by another way')

def main():
    for item in range(2):
        errors = example()
    print '\n'.join(errors)

main()

печатает следующие

Attempt to fix it
Attempt to fix it by another way
Attempt to fix it
Attempt to fix it by another way
44
задан SRK 3 January 2012 в 07:34
поделиться

2 ответа

Если функция печатает на System.out, вы можете записать этот вывод с помощью метода System.setOut, чтобы изменить System.out, чтобы перейти к PrintStream, предоставленному вами. Если вы создаете PrintStream, подключенный к ByteArrayOutputStream, вы можете записать вывод как String.

Пример:

    // Create a stream to hold the output
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos);
    // IMPORTANT: Save the old System.out!
    PrintStream old = System.out;
    // Tell Java to use your special stream
    System.setOut(ps);
    // Print some output: goes to your special stream
    System.out.println("Foofoofoo!");
    // Put things back
    System.out.flush();
    System.setOut(old);
    // Show what happened
    System.out.println("Here: " + baos.toString());

Эта программа печатает только одну строка:

    Here: Foofoofoo!
86
ответ дан Ernest Friedman-Hill 20 August 2018 в 15:37
поделиться
  • 1
    Не забывайте, когда вы закончите, вызовите System.out.flush (), а затем переключите System.out обратно в обычный (или, вернее, предыдущий) System.out. Я вижу, что @Ernest добавил это в свой код. – user949300 3 January 2012 в 07:42
  • 2
    Кроме того, не забывайте, что это создает проблемы с потоками, а не только для этого метода (который вы можете решить, синхронизируя его), но для любого другого кода, который печатает на stdout. baos.toString() может быть легко "Foofohello worldofoo!" – yshavit 3 January 2012 в 08:01
  • 3
    @Ernest: получилось спасибо ... – SRK 5 January 2012 в 12:35
  • 4
    как получить строку из объекта ps? для него нет метода ... – user 5 July 2016 в 14:33
  • 5
    @tuskiomi Строка происходит от ByteArrayOutputStream.toString () - см. последнюю строку кода примера. – Ernest Friedman-Hill 5 July 2016 в 16:20

Вот класс утилиты ConsoleOutputCapturer. Он позволяет выводить выход на существующую консоль, однако позади сцены сохраняется захват выходного текста. Вы можете управлять захватом с помощью методов старт / стоп. Другими словами, вызовите начало запуска захвата вывода консоли, и как только вы закончите захват, вы можете вызвать метод stop, который возвращает значение String, содержащее вывод консоли для временного окна между вызовами start-stop. Этот класс не является потокобезопасным.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

public class ConsoleOutputCapturer {
    private ByteArrayOutputStream baos;
    private PrintStream previous;
    private boolean capturing;

    public void start() {
        if (capturing) {
            return;
        }

        capturing = true;
        previous = System.out;      
        baos = new ByteArrayOutputStream();

        OutputStream outputStreamCombiner = 
                new OutputStreamCombiner(Arrays.asList(previous, baos)); 
        PrintStream custom = new PrintStream(outputStreamCombiner);

        System.setOut(custom);
    }

    public String stop() {
        if (!capturing) {
            return "";
        }

        System.setOut(previous);

        String capturedValue = baos.toString();             

        baos = null;
        previous = null;
        capturing = false;

        return capturedValue;
    }

    private static class OutputStreamCombiner extends OutputStream {
        private List<OutputStream> outputStreams;

        public OutputStreamCombiner(List<OutputStream> outputStreams) {
            this.outputStreams = outputStreams;
        }

        public void write(int b) throws IOException {
            for (OutputStream os : outputStreams) {
                os.write(b);
            }
        }

        public void flush() throws IOException {
            for (OutputStream os : outputStreams) {
                os.flush();
            }
        }

        public void close() throws IOException {
            for (OutputStream os : outputStreams) {
                os.close();
            }
        }
    }
}
17
ответ дан Bilesh Ganguly 20 August 2018 в 15:37
поделиться
  • 1
    Отлично работает, хорошая работа! – Itsik Mauyhas 9 June 2016 в 12:09
  • 2
    Действительно приятное решение, хотя я бы предложил одно небольшое дополнение, вызовите метод close () для потока baos в методе stop (), прежде чем устанавливать его в null, чтобы освободить все ресурсы. – mmierins 20 July 2016 в 09:43
  • 3
    Отличная работа! :) – Developer66 6 January 2018 в 12:26
Другие вопросы по тегам:

Похожие вопросы: