What is the correct way to remove a stream from stdout so that another stream can be added?

I am starting a process in Dart that attaches the stdout stream to stdout so that the results can be printed on the terminal as follows:

Process.start(executable, ['list','of','args']).then((proc) {
  stdout.addStream(proc.stdout);
  stderr.addStream(proc.stderr);
  return proc.exitCode;
});

However, as soon as this ends, I would like to start a new process and start it again (the function it is in will be called several times). Sometimes I get an error message:

Uncaught Error: Bad State: StreamSink is already bound to a stream

Looking at the dart docs, it looks like I might need to do something like stdout.close()or stdout.flush(), but they don't seem to solve the problem. What is the correct way to handle multiple streams in a streamsink-related sequence?

+4
source share
3 answers

addStream , , . , addStream StreamSink.

, / , 2 :

  • () .
  • addStream.

:

Process.start(executable, ['list','of','args']).then((proc) async {
  await stdout.addStream(proc.stdout);  // Edit: don't do this.
  await stdout.addStream(proc.stderr);
  return proc.exitCode;
});

async await .

: , stderr . ( ).

, Process.run:

Process.run(executable, ['list','of','args']).then((procResult) {
  stdout.write(procResult.stdout);
  stdout.write(procResult.stderr);
  return procResult.exitCode;
});

stdout stderr.

+4

addStream . "", "" , . , , , . , .

( ) , . , , , . - :

Stream interleave(Iterable<Stream> streams) {
  List subscriptions = [];
  StreamController controller;
  controller = new StreamController(
    onListen: () {
      int active = 0;
      void done() {
        active--;
        if (active <= 0) controller.close();
      }
      for (var stream in streams) {
        active++;
        var sub = stream.listen(controller.add, 
                                onError: controller.addError,
                                onDone: done);
        subscriptions.add(sub);             
      }
    },
    onPause: () {
      for (var sub in subscriptions) { sub.pause(); }
    }, 
    onResume: () {
      for (var sub in subscriptions) { sub.resume(); }
    },
    onCancel: () {
      for (var sub in subscriptions) { sub.cancel(); }  
    }
  );
  return controller.stream;
}

( !)

+3

StreamSubscription subscr = proc.stdout.listen(io.stdout.add);
...
subscr.cancel();

class StdOutHandler { 
  IOSink sink; 
  call(data) => sink.add(); 
}

void main() {
  var proc = await Process.start(...);
  var stdoutHandler = new StdOutHandler()..sink = stdout;
  var subscription = proc.stdout.listen(stdoutHandler);
  ....
  stdoutHandler.sink = ...
} 
0

Source: https://habr.com/ru/post/1589479/


All Articles