Как скопировать InputStream в Apache TeeOutputStream, который ожидает OutputStream?

Я адаптировал образец Apache IOUtil для работы с WeatherTelnet образец немного по-другому. Хотя в комментариях для WeatherTelnet указано, что:

Класс TelnetClient, используемый сам по себе, в основном предназначен для автоматизация доступа к ресурсам telnet, а не интерактивное использование.

Я хотел бы разделить вывод, используя Apache TeeOutputStream, но API ветки OutputStream, тогда как TelnetClient "вывод" имеет вид InputStream, так что, конечно, его можно прочитать. Удобно, что утилита Apache copyStream будет копировать InputStream в OutputStream.

1.) Как скопировать InputStream в OutputStream в printKindaWorks или printToFile? 2.) Как я могу либо записать OutputStream в файл, либо tee?

трюк заключается в том, чтобы выполнять эти операции в реальном времени, , пока пользователь взаимодействует с сервером погоды.

Я сделал все возможное, чтобы посмотреть исходный код для copyStream и использовать его для справки, но он просто не работает. Я еще не посмотрел на внутренности для реализации Apache tee.

Класс утилиты:

package apache;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.net.io.Util;

public final class IOUtil {

    private static final Logger log = Logger.getLogger(IOUtil.class.getName());

    private static void readFromConsole(final OutputStream outputStream) {
        Thread read = new Thread() {

            @Override
            public void run() {
                int ch;

                try {
                    while ((ch = System.in.read()) != -1) {
                        outputStream.write(ch);
                        outputStream.flush();
                    }
                } catch (IOException ioe) {
                    log.warning(ioe.toString());
                }
            }
        };
        read.start();
    }

    private static void writeToConsole(final InputStream inputStream) {
        Thread write = new Thread() {

            @Override
            public void run() {
                try {
                    Util.copyStream(inputStream, System.out);
                } catch (IOException ioe) {
                    log.warning(ioe.toString());
                }
            }
        };
        write.start();
    }

    private static void printKindaWorks(final InputStream inputStream) {
        Thread write = new Thread() {

            @Override
            public void run() {
                PrintStream printStream = null;
                try {
                    File file = new File("weather.log");
                    FileOutputStream fos = new FileOutputStream(file, true);
                    printStream = new PrintStream(fos);
                    Util.copyStream(inputStream, printStream);
                } catch (IOException ioe) {
                    log.warning(ioe.toString());
                }
            }
        };
        write.start();
    }

//                TeeOutputStream tee = new TeeOutputStream(inputStream, bis);   
    private static void writeToFile(final InputStream inputStream) throws FileNotFoundException, IOException {
        final String fname = "whether.log";
        File f = new File(fname);
        f.createNewFile();
        Thread fileWriter = new Thread() {

            @Override
            public void run() {
                char c = 0;
                int r = 0;
                try {
                    while ((r = inputStream.read()) != -1) {
                        c = (char) r;
                        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fname, true)));
                        out.print(c);
                        out.close();
                    }
                } catch (IOException ex) {
                    Logger.getLogger(IOUtil.class.getName()).log(Level.SEVERE, null, ex);
                }


            }
        };
        fileWriter.start();
    }

    public static void readWriteLog(final InputStream inputStream, final OutputStream outputStream) throws FileNotFoundException, IOException {
        readFromConsole(outputStream);
        writeToConsole(inputStream);
        writeToFile(inputStream);  //doesn't write much
  //      printKindaWorks(inputStream);       //blocks writeToConsole ?
    }
}

и драйвер:

package weather;

import apache.IOUtil;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.commons.net.telnet.TelnetClient;

public class Weather {

    public Weather() {
    }

    public static void main(String[] args) throws UnknownHostException, IOException {
        int port = 3000;
        InetAddress host = InetAddress.getByName("rainmaker.wunderground.com");
        TelnetClient telnetClient = new TelnetClient();
        telnetClient.connect(host, port);
        IOUtil.readWriteLog(telnetClient.getInputStream(), telnetClient.getOutputStream());
    }
}

Пожалуйста, рассмотрите код под ASL.

Пока я "регистрирую" InputStream, я не работаю над проблемой ведения журнала, запись в файл предназначена только для иллюстрации. Я просто хочу разделить InputStream, пока пользователь взаимодействует с сервером погоды.

Ответы

Ответ 1

Вам нужно создать экземпляр TeeOutputStream, который обертывает System.out и файл журнала. Затем создайте поток, который копирует telnet InputStream в TeeOutputStream. (вы можете использовать только один поток, потребляющий telnet InputStream)

Ответ 2

Не то, что я хочу, скорее использовал бы Apache tee, но это делает работу (неуклюже):

package apache;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

public final class IOUtil {

    private static final Logger log = Logger.getLogger(IOUtil.class.getName());

    private static void readFromConsole(final OutputStream outputStream) {
        Thread read = new Thread() {

            @Override
            public void run() {
                int ch;

                try {
                    while ((ch = System.in.read()) != -1) {
                        outputStream.write(ch);
                        outputStream.flush();
                    }
                } catch (IOException ioe) {
                    log.warning(ioe.toString());
                }
            }
        };
        read.start();
    }

//                TeeOutputStream tee = new TeeOutputStream(inputStream, bis);   
    private static void readInput(final InputStream inputStream) throws FileNotFoundException, IOException {
        Thread readInput = new Thread() {

            @Override
            public void run() {
                char c = 0;
                int r = 0;
                try {
                    while ((r = inputStream.read()) != -1) {
                        c = (char) r;
                        printToConsole(c);
                        logToFile(c);
                    }
                } catch (IOException ex) {
                    Logger.getLogger(IOUtil.class.getName()).log(Level.SEVERE, null, ex);
                }


            }

            private void logToFile(char c) throws IOException {
                String fname = "whetherOrNot.log";
                File f = new File(fname);
                f.createNewFile();
                PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fname, true)));
                out.print(c);
                out.flush();
                out.close();
            }

            private void printToConsole(char c) {
                System.out.print(c);
            }
        };
        readInput.start();
    }

    public static void readWriteLog(final InputStream inputStream, final OutputStream outputStream) throws FileNotFoundException, IOException {
        readFromConsole(outputStream);
        readInput(inputStream);
    }
}