Как заглянуть в STDIN с Delphi 7? - PullRequest
1 голос
/ 02 июня 2011

В консольном приложении Delphi 7 как я могу проверить, содержит ли stdin символ без блокировки до его ввода?

Я планирую, что эта консольная программа будет выполняться программой с графическим интерфейсом, и ееSTDIN будет записан программой GUI.

Поэтому я хочу, чтобы мое консольное приложение периодически проверяло STDIN, но я не могу найти способ сделать это без блокировки.

Я посмотрелна этот ответ , который дает мне поток, указывающий на stdin, но до сих пор нет способа "посмотреть", насколько я вижу.

Ответы [ 4 ]

4 голосов
/ 02 июня 2011

Я думаю, вы уже нашли правильный способ чтения стандартного ввода. Он предназначен для блокировки, когда больше нечего читать.

Стандартный способ справиться с этим - использовать отдельную резьбу для обработки трубы. Когда он получает новые данные от stdin, он сообщает об этом потоку обработки, например, с помощью механизма передачи сообщений.

Сказав все это, если вы действительно хотите опросить, вы можете позвонить в PeekNamedPipe, чтобы проверить, есть ли данные в канале.

1 голос
/ 03 июня 2011

Нет другого пути (насколько я знаю), как чтение из трубы внутри отдельного потока. В противном случае, как вы уже видели, операция чтения файла будет заблокирована. Я написал пример, как это сделать, пример проекта также доступен: перенаправление stdoutput

Edit: Хорошо, читая ваш вопрос в другой раз, я понимаю, что ваша проблема заключается в консольной программе, а не в вызывающем приложении. Интересно, что ожидает ваше консольное приложение, обычно консольное приложение знает, когда оно нуждается в вводе, и не может продолжить работу, пока пользователь не введет эту информацию. Вам нужно проверить выход?

1 голос
/ 02 июня 2011

Как и в другом ответе, вы можете использовать потоки, но даже тогда у вас могут возникнуть проблемы (при использовании метода потоков), если вы также не исследуете перекрывающийся ввод-вывод.

Обычно я использую перекрывающийся ввод-вывод с последовательными портами, а не stdin, где обычно требуется «прочитать символ, если он готов», и где неблокирующий ввод-вывод - обычный способ работы. Вы должны быть в состоянии приспособить показанную технику здесь . Однако, если бы я писал приложение, которое управлялось клавиатурой (вместо того, чтобы просто управлять, скажем, файлом, перенаправленным на стандартный ввод), я бы отказался от StdIN и использовал модуль типа CRT. Итак, если вы не против отказаться от StdIn и просто хотите иметь модель ввода на основе клавиатуры, вы можете взглянуть на консольные API и отказаться от очень ограничивающих возможностей StdIn. Для примера функции "kbhit", которая использует API консоли Win32, см. здесь .

0 голосов
/ 02 июня 2011

Для потока, если вы .Read (), результатом функции является число прочитанных байтов, которое будет равно нулю, если там ничего не было, даже если вы запросили больше. Из справки Delphi для Classes.TStream.Read:

Чтение используется в тех случаях, когда число байтов для чтения из потока не обязательно фиксировано. Он пытается прочитать до количества байтов в буфере и возвращает количество фактически прочитанных байтов.

...