Существует ли простой способ проверки, будет ли экземпляр Ruby IO блокироваться при чтении ()? - PullRequest
14 голосов
/ 31 мая 2009

Я ищу метод в Ruby, который в основном такой:

io.ready_for_read?

Я просто хочу проверить, есть ли у данного объекта IO (в моем случае, результат вызова popen) вывод, т. Е. Последующий вызов io.read(1) не заблокирует.

Я вижу два варианта, ни один из которых мне не нравится:

  1. io.read_nonblock - слишком тонкая абстракция Unix read() - я не хочу иметь дело с errno обработкой ошибок.

  2. io.select с таймаутом 0 - скрывает цель этой простой операции.

Есть ли лучшая альтернатива, которую я упустил из виду?

Ответы [ 3 ]

8 голосов
/ 16 ноября 2009

Немного поздно, но если вы require 'io/wait', вы можете использовать ready?, чтобы убедиться, что ввод-вывод может быть прочитан без блокировки. Конечно, в зависимости от того, сколько вы намереваетесь читать (и как вы планируете это делать), ваш объект ввода-вывода все еще может блокироваться, но это должно помочь. Я не уверен, поддерживается ли эта библиотека на всех платформах, и я также не знаю, почему эта функция была отделена от остальной части библиотеки ввода-вывода. Подробнее здесь: http://ruby -doc.org / stdlib / libdoc / io / wait / rdoc /

6 голосов
/ 04 июня 2009

Я готов заключить, что нет, не существует простого способа сделать это. Согласно предложению Питера Купера, здесь IO#ready_for_read?:

class IO
  def ready_for_read?
    result = IO.select([self], nil, nil, 0)
    result && (result.first.first == self)
  end
end
0 голосов
/ 17 февраля 2011

В Windows я видел некоторые несоответствия с IO / wait . Рубин, который я здесь сейчас имею:

ruby ​​1.9.2p136 (2010-12-25) [i386-mingw32]

В этом случае реализованы оба nread и ready? , но они возвращают ошибочные результаты. В другой версии, которую я использовал готов? все еще был сломан, а nread даже не существовало.

Одна из возможностей - использовать io.stat.size , который сообщает вам количество байтов, доступных для чтения в потоке ввода-вывода. http://www.ruby -doc.org / ядро ​​/ классов / Файл / Stat.html

Документация предполагает, что это для файлов, но я использовал его на каналах, подключенных к отдельному процессу (через Ruby's Open3.popen3). Пока это работает для меня.

...