我在Dart中的许多地方都使用了stdout.write(),以免出现新的一行。一切正常,但最近已从同步更改为异步。我刚刚在Win7-32​​和Win8-64上升级到Dart 28355。

以下描述了更改:

“发生了什么变化?
在所有平台上,写入stdout和stderr以前都是阻塞的。作为清理的一部分,它现在与dart:io中的任何其他Streams一样是异步/非阻塞的。
如何更新我的代码?
除少数情况下,调用“exit”时,大多数代码应该像以前一样工作:”

我想要实现的一个小例子如下:

import 'dart:io';

main() {
  String sCorrectYn;
  while (sCorrectYn != "y") {
    String sName = fInputString("Enter Name : ");
    sCorrectYn = fInputString("Details Correct? (y/n) : ");
  }
}

String fInputString(String sPrompt) {
  stdout.write("\n$sPrompt");
  return stdin.readLineSync().toLowerCase();
}

在win8上运行上述命令时的终端输出如下:
c:\Users\boh\dart-dev1\testpg001>dart testinput001.dart

Enter Name : abcd
n
xxxx
n
zzzz
y

Details Correct? (y/n) :
Enter Name :
Details Correct? (y/n) :
Enter Name :
Details Correct? (y/n) :
c:\Users\boh\dart-dev1\testpg001>

上面发生的是,所有终端输出都在我最终输入“y”之后出现,这终止了程序并刷新了输出缓冲区(它出现了)。第一个终端输出“Enter Name:”是应该出现的唯一输出。

似乎没有用于标准输出的“刷新”方法。

我在将来使用stdout进行了实验,但是无法使其正常运行。

我怎样才能使它以所需的方式工作?

使用stdout.write(),以下代码也无法按需工作:
import 'dart:io';

main() {
  String sInput;
  stdout.write("\nEntry 1 : ");
  sInput = stdin.readLineSync();
  print("Date Entered (1) was : $sInput");
  stdout.write("\nEntry 2 : ");
  sInput = stdin.readLineSync();
  print("Date Entered (2) was : $sInput");
  stdout.write("\nEntry 3 : ");
  sInput = stdin.readLineSync();
  print("Date Entered (3) was : $sInput");
  stdout.write("\nEntry 4 : ");
  sInput = stdin.readLineSync();
  print("Date Entered (4) was : $sInput");
  stdout.write("\nEntry 5 : ");
  sInput = stdin.readLineSync();
  print("Date Entered (5) was : $sInput");
}

上面的终端显示显示第一行“Entry 1:”仅是在使用stdout.write()时需要时显示的行:
c:\Users\boh\dart-dev1\testpg001>dart testinput003.dart

Entry 1 : aaa
Date Entered (1) was : aaa
bbb
Date Entered (2) was : bbb
ccc
Date Entered (3) was : ccc
ddd
Date Entered (4) was : ddd
eee
Date Entered (5) was : eee

Entry 2 :
Entry 3 :
Entry 4 :
Entry 5 :
c:\Users\boh\dart-dev1\testpg001>

最佳答案

可以通过使用IOSink创建可以等待的新StreamController来实现“刷新” Stream的功能。我已经使用writeAndFlush帮助器方法重写了您的示例。

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

main() {
  void loop() {
    fInputString("Enter Name : ")
      .then((_) => fInputString("Details Correct? (y/n) : "))
      .then((sCorrectYn) {
        if (sCorrectYn != "y") loop();
      });
  }
  loop();
}

Future<String> fInputString(String sPrompt) {
  return writeAndFlush(stdout, "\n$sPrompt")
    .then((_) {
      return stdin.readLineSync().toLowerCase();
    });
}

Future writeAndFlush(IOSink sink, object) {
  return sink.addStream(
    (new StreamController()
      ..add(UTF8.encode(object.toString()))
      ..close())
      .stream);
}

我们应该考虑向IOSink添加flush来做到这一点。

请注意,这实际上不是在IO级别上“刷新”,而是将等待Stream读取结束,即等待操作系统可能暂停和恢复Stream

09-30 14:29
查看更多