如何将stdin(多行)捕获到Dart中的String?

时间:2015-03-01 05:02:10

标签: dart dart-io

我有一个Dart命令行程序,希望能够将数据从shell传递到Dart程序(例如,cat file.txt | dart my_program.dart或接受输入,直到用户使用 Ctrl + d )。通过在线教程,我发现从stdin保存输入的唯一文档是stdin.readLineSync()。但是,顾名思义,这只会读取第一行。

如何将stdin的全部内容捕获到String?此外,如果用户试图管理一个非常大的文件,是否会有任何安全问题?字符串可以有多长时间?我怎样才能防范这个?

感谢您的帮助!

3 个答案:

答案 0 :(得分:3)

如果以交互方式使用以下程序将回显您的输入,但将每个字符大写。

您也可以将文件传输给它。

dart upper_cat.dart < file.txt

这将输出每个大写字母的文件。

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

main() {

  // Stop your keystrokes being printed automatically.
  stdin.echoMode = false;

  // This will cause the stdin stream to provide the input as soon as it
  // arrives, so in interactive mode this will be one key press at a time.
  stdin.lineMode = false;

  var subscription;
  subscription = stdin.listen((List<int> data) {

    // Ctrl-D in the terminal sends an ascii end of transmission character.
    // http://www.asciitable.com/
    if (data.contains(4)) {
      // On my computer (linux) if you don't switch this back on the console
      // will do wierd things.
      stdin.echoMode = true;

      // Stop listening.
      subscription.cancel();
    } else {

      // Translate character codes into a string.
      var s = LATIN1.decode(data);

      // Capitalise the input and write it back to the screen.
      stdout.write(s.toUpperCase());
    }
  });

}

还有console库可以帮助解决这类问题。我没有尝试过,但试一试并报告回来;)

以下示例处理UTF8输入 - 上面的示例需要1个字节的字符作为输入。

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

main() {

  stdin.echoMode = false;
  stdin.lineMode = false;

  var subscription;
  subscription = stdin
    .map((List<int> data) {
      if (data.contains(4)) {
        stdin.echoMode = true;
        subscription.cancel();
      }
      return data;
    })
    .transform(UTF8.decoder)
    .map((String s) => s.toUpperCase())
    .listen(stdout.write);
}

答案 1 :(得分:0)

您可以使用

import 'dart:io' as io;
import 'dart:async' show Future, Stream, StreamSubscription;
import 'dart:convert' show UTF8;

void main() {
  StreamSubscription subscr = io.stdin.transform(UTF8.decoder).listen((data) => 
      print(data));
}

您可以使用

控制是否应该接收更多数据
subscr.pause();
subscr.resume();

如果我没记错的话,监听stdin以16kb的块传递数据(由Dart定义的io缓冲区大小)这允许您接收可以处理的数据量。 如果你想在内存中保留一个大字符串,你需要有可用的内存。

另见
- https://stackoverflow.com/a/26343041/217408(设置VM内存)
- https://stackoverflow.com/a/12691502/217408
- https://stackoverflow.com/a/28039661/217408

答案 2 :(得分:0)

我研究了stdin.readLineSync()的代码,并且能够修改它以满足我的需求:

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

String readInputSync({Encoding encoding: SYSTEM_ENCODING}) {
  final List input = [];
  while (true) {
    int byte = stdin.readByteSync();
    if (byte < 0) {
      if (input.isEmpty) return null;
      break;
    }
    input.add(byte);
  }
  return encoding.decode(input);
}

void main() {
  String input = readInputSync();
  myFunction(input); // Take the input as an argument to a function
}

我需要从stdin同步读取以暂停程序,直到读取整个stdin(直到文件结尾或 Ctrl + d )。 / p>

感谢您的帮助!我不认为如果没有你的帮助我就能弄清楚。