Как скопировать 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);
}
}