gpt4 book ai didi

asynchronous - dart将数据从stdin和stderr传递到另一个进程的stdin

转载 作者:行者123 更新时间:2023-12-03 03:57:17 25 4
gpt4 key购买 nike

这确实是来自以下方面的问题:

Dart: How to pass data from one process to another via streams

我使用dart生成两个进程。

让我们将这两个进程称为“lhs”和“rhs”。
(lhs-左侧,rhs-右侧)。

第一个进程(lhs)写入stdout和stderr。
我需要将所有数据从第一个进程(lhs)传输到第二个进程(rhs)的stdin。

在上述堆栈溢出中,答案是使用“管道”方法将数据从lhs.stdout流到rhs.stdin。

鉴于我现在想从lhs的两个流(stdout和stderr)写入数据,pipe方法不起作用,因为它仅支持单个流,并且您不能在rhs的stdin上调用两次管道(抛出错误说明正确,您不能两次调用addStream)。

因此,我尝试了以下似乎部分起作用的代码,但我只看到lhs的stderr流中的第一个字符,然后一切都完成了(两个lhs的流都调用了onDone方法)。

一些细节可以帮助您了解这里发生的情况。

在下面的代码中,“lhs”是对“dart --version”的调用。当dart写入其版本字符串时,会将其写入stderr,而不会将任何内容写入stdout。

我将“head”用作第二个过程-“rhs”。它的工作是简单地从lhs接收stdout和stderr的组合输出并将其打印到控制台。

下面的代码运行的输出是:

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;
}


最佳答案

我认为您使用listen()将事件转发到rhsProcess.stdin的解决方案将起作用。您可以使用await代替then()回调来清理它,并删除Completer。您可以使pipeTo()返回Future<void>,或者根据需要使用waitFor(pipeTo())

这是一个简洁的示例:

import 'dart:async';
import 'dart:convert';
import 'dart:io';

void main() {
var dart = Process.start('dart', ['--version']);
var head = Process.start('head', ['-n', '1']);
pipeTo(dart, head);
}

Future<void> pipeTo(Future<Process> lhs, Future<Process> rhs) async {
var lhsProcess = await lhs;
var rhsProcess = await rhs;
lhsProcess.stdout.listen(rhsProcess.stdin.add);
lhsProcess.stderr.listen(rhsProcess.stdin.add);
rhsProcess.stdout.transform(utf8.decoder).listen(print);
}

注意:我将 -n 1传递给head,否则程序将永远不会退出。

关于asynchronous - dart将数据从stdin和stderr传递到另一个进程的stdin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60015095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com