Я использую API (для получения дополнительной информации см. Ниже), который принимает OutputStream для захвата данных. Вместо этого я хочу предоставить Consumer из Strings , который использует строку данных за строкой. Следовательно, я должен написать реализацию OutputStream, которая оборачивает такого Потребителя. Это самое простое, о чем я могу подумать:
import java.io.OutputStream;
import java.util.Objects;
import java.util.function.Consumer;
public class OutputStreamConsumer extends OutputStream {
private final Consumer<String> consumer;
private final StringBuilder sb = new StringBuilder();
public OutputStreamConsumer(Consumer<String> consumer) {
this.consumer = Objects.requireNonNull(consumer);
}
@Override
public void write(int b) {
char c = (char) b;
if (c == '\r') {
return;
}
if (c == '\n') {
consume();
return;
}
this.sb.append(c);
}
@Override
public void close() {
if (sb.length() != 0) {
consume();
}
}
private void consume() {
this.consumer.accept(this.sb.toString());
this.sb.delete(0, Integer.MAX_VALUE);
}
}
Однако этого, вероятно, недостаточно для производственного кода с точки зрения кодирования и производительности . Я думаю, что необходимая логика уже содержится в InputStreamReader и BufferedReader , но я не могу использовать эти классы в этом сценарии. Каков наилучший способ написать этот тип OutputStream? Какие классы jdk можно использовать, чтобы избежать написания связки низкоуровневой кодировки, обработки конца строки и т. Д.
Конкретный вариант использования
В проекте плагина GradleЯ запускаю внешний процесс, используя API проекта Gradle: ExecSpec . Там я могу установить OutputStreams, используя методы setStandardOutput и setErrorOutput , чтобы захватить выходные данные процесса.