Вопросы при использовании потоков с вводом из Linux каналов - PullRequest
0 голосов
/ 08 февраля 2020

Следующие вопросы для начинающих Дарт и RxDart. Версии Dart и RxDart являются самыми последними на вчерашний день.

В следующем примере программы Dart, сохраненной в файле 't.dart', только одна из двух опций, A или B, не используется. прокомментировал за один раз. Перед его выполнением создается « fifo » путем выполнения « mkfifo fifo ». Результаты выполнения приведены ниже.

Вопросы :

  1. Почему Stream открывается с использованием Файл показывает только один полученный байт, тогда как при использовании stdin Stream и входе с того же fifo видит все входные данные?
  2. Почему RxDart оператор дубль выдает только одно значение?

Option-A : выполняется как ' dart t.dart 'в одном окне и' (для i в AB C D; do echo -n $ i; sleep 1; done)> fifo 'другое окно в том же каталоге. Вывод:

byte count: 1, bytes: A
File is now closed.

Опция-B : Выполнено как ' cat fifo | дротик t.dart 'в одном окне и' (для i в AB C D; do echo -n $ i; sleep 1; done)> fifo '. Вывод:

byte count: 1, bytes: A
byte count: 1, bytes: B
byte count: 1, bytes: C
byte count: 1, bytes: D
File is now closed.

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

main(List<String> args) {

  // Option-A
  // Stream<List<int>> inputStream = File("fifo").openRead();

  // Option-B
  // Stream<List<int>> inputStream = stdin;

  inputStream
    .transform(utf8.decoder)
    .take(16)
    .listen((bytes) => print('byte count: ${bytes.length}, bytes: ${bytes}'),
        onDone: () { print('File is now closed.'); },
        onError: (e) { print(e.toString()); }
      );
}

1 Ответ

0 голосов
/ 08 февраля 2020

(Я недостаточно осведомлен о том, как работает ввод / вывод Dart, чтобы дать твердый ответ, поэтому я предпочитаю, что происходит.)

Похоже, происходит то, что в варианте A вы создаете поток для еще не существующего файла. Дарт видит, что файл еще не существует, поэтому публикация в потоке задерживается. Затем, когда вы запускаете сценарий echo, он создает файл и добавляет к нему первое значение «A», после чего вы просите его перевести в спящий режим на 1 секунду.

В течение этой секунды Дарт видит, что файл теперь существует, и начинает потоковую передачу данных из него. Он читает «А», а затем достигает конца файла. Что касается Дартса, это конец истории, поэтому он закрывает поток. К тому времени, когда сценарий добавляет в файл «B», «C» и «D», Дарт уже завершил выполнение программы и вышел из процесса.

В варианте B вместо того, чтобы сказать Стремясь к потоковой передаче из файла, вы подключаетесь к входному потоку процесса, который (насколько я знаю) будет оставаться открытым до тех пор, пока в него записывается что-то. У меня есть ощущение, что для понимания того, что именно происходит, требуется лучшее знание cat и того, как работает трубопровод в терминале, чем у меня есть, но я верю, что если коротко, то программа cat знает, что файл пишется, что предотвращает его преждевременное завершение. Таким образом, всякий раз, когда cat получает новые данные, он передает эти данные во входной поток процесса Dart.

Возвращаясь к коду Dart, вы слушаете входной поток, который все еще ожидает данные, начиная с cat все еще выполняется, и как таковое не закрылось. Только после завершения процесса записи файла cat распознает, что он достиг истинного конца файла, и завершает работу, после чего Дарт узнает, что больше не собирается получать данные, и закрывает входной поток.

(Как я уже сказал, это всего лишь мое лучшее предположение, но я подозреваю, что простой способ определить это - посмотреть, когда заканчивается ваш сценарий Dart и другой сценарий. Если в варианте A Дарт заканчивает задолго до того, как делает сценарий, и в Варианте Б они заканчивают sh примерно в одно и то же время, что было бы для меня достаточным доказательством того, что вышесказанное действительно происходит.)

...