Это действительно следствие из:
Dart: Как передавать данные от одного процесса другому через потоки
Я использую dart для порождения двух процессов .
Давайте назовем эти два процесса "lhs" и "rhs". (lhs - левая сторона и rhs - правая сторона).
Первый процесс (lhs) записывает в stdout и stderr. Мне нужно передать все данные из первого процесса (lhs) в stdin второго процесса (rhs).
В вышеупомянутом переполнении стека ответом было использование метода pipe для потоковой передачи данных из lhs.stdout в rhs.stdin.
Учитывая, что теперь я хочу записать данные из обоих потоков lhs (stdout и stderr), метод pipe не работает, поскольку он поддерживает только один поток, и вы можете ' t вызываем pipe дважды в sthin rhs (выдается сообщение о том, что вы не можете дважды вызвать addStream).
Итак, я попробовал следующий код, который, кажется, частично работает, но я вижу только первый символ из потока lhs stderr, а затем все завершается (методы onDone вызываются в обоих потоках lhs).
Некоторые подробности, помогающие понять, что здесь происходит.
Ниже code 'lhs' - это вызов 'dart --version'. Когда dart записывает свою строку версии, он записывает ее в stderr, а в stdout ничего не записывается.
Я использую 'head' в качестве второго процесса - 'rhs'. Его работа состоит в том, чтобы просто получить объединенный вывод stdout и stderr от lhs и распечатать его на консоли.
Вывод из прогона приведенного ниже кода:
lhs exitCode=0
done
listen: stderr
listen: stderr written
done err
import 'dart:async';
import 'dart:cli';
import 'dart:io';
Future<void> main() async {
var dart = start('dart', ['--version']);
var head = start('head', ['-n', '5']);
pipeTo(dart, head);
}
void pipeTo(Future<Process> lhs, Future<Process> rhs) {
var complete = Completer<void>();
// wait for the lhs and rhs processes to
// start and then start piping lhs
// output to the rhs input.
lhs.then((lhsProcess) {
rhs.then((rhsProcess) {
// write stdout from lhs to stdin of rhs
lhsProcess.stdout.listen((datum) {
print('listen');
rhsProcess.stdin.add(datum);
print('listen written');
}
, onDone: () {
print('done');
complete.complete();
}
, onError: (Object e, StackTrace s) =>
print('onError $e')
,cancelOnError: true);
// write stderr from lhs to stdin of rhs.
lhsProcess.stderr.listen((datum) {
print('listen: stderr');
rhsProcess.stdin.add(datum);
print('listen: stderr written');
}
, onDone: () {
print('done err');
if (!complete.isCompleted) complete.complete();
}
, onError: (Object e, StackTrace s) =>
print('onError $e')
, cancelOnError: true);
lhsProcess.exitCode.then((exitCode) {
print('lhs exitCode=$exitCode');
});
rhsProcess.exitCode.then((exitCode) {
print('rhs exitCode=$exitCode');
});
});
});
waitFor(complete.future);
}
Future<Process> start(String command, List<String> args) async {
var process = Process.start(
command,
args,
);
return process;
}