Search code examples
iostreamstdindartdart-io

How can I do stdin.close() with the new Streams API in Dart?


I ask user for input in my command line (dart:io) app. After I get my answer from the user, I want to unsubscribe from the Stream. Then, later, I may want to listen to it again (but with different listener, so pause() and resume() don't help me).

On startup, I have this:

cmdLine = stdin
          .transform(new StringDecoder());

Later, when I want to gather input:

cmdLineSubscription = cmdLine.listen((String line) {
  try {
    int optionNumber = int.parse(line);
    if (optionNumber >= 1 && optionNumber <= choiceList.length) {
      cmdLineSubscription.cancel();
      completer.complete(choiceList[optionNumber - 1].hash);
    } else {
      throw new FormatException("Number outside the range.");
    }
  } on FormatException catch (e) {
    print("Input a number between 1 and ${choiceList.length}, please.");
  }
});

This works as intended, but it leaves stdin open at the end of program execution. With the previous API, closing stdin was as easy as calling stdin.close(). But with the new API, stdin is a Stream, and those don't have the close method.

I think that what I'm doing is closing (read: unsubscribing from) the transformed stream, but leaving the raw (stdin) stream open.

Am I correct? If so, how can I close the underlying stdin stream on program exit?


Solution

  • To close stdin, you just unsubscribe from it:

    cmdLineSubscription.cancel();
    

    This is the equivalent way of doing it. So your intuition was right. I'm not sure if I understood the question -- was there a problem with this approach?