Gibt es eine einfache Methode zum Überprüfen, ob eine Ruby-IO-Instanz auf Lese-Block wird ()?
-
06-09-2019 - |
Frage
Ich bin für eine Methode in Ruby suchen, die im Grunde ist dies:
io.ready_for_read?
ich, ob ein gegebenes IO
Objekt nur überprüfen will (in meinem Fall das Ergebnis einer popen
Call) hat Ausgang zur Verfügung, das heißt einen Follow-up Anruf io.read(1)
nicht blockieren.
Dies sind die zwei Optionen, die ich sehe, von denen keines Ich mag:
-
io.read_nonblock
- zu dünn eine Abstraktion von Unixread()
-. Ich will nicht miterrno
Fehlerbehandlung behandeln -
io.select
mit Timeout 0 - verschleiert den Zweck dieser einfachen Bedienung .
Gibt es eine bessere Alternative, die ich übersehen habe?
Lösung
Ein bisschen spät, aber wenn Sie require 'io/wait'
, können Sie ready?
verwenden, um zu überprüfen, dass die IO ohne Blockierung gelesen werden. Zugegeben, je nachdem, wie viel Sie beabsichtigen, sich auf das Lesen (und wie Sie planen, es zu tun) Ihr IO-Objekt kann immer noch blockieren, aber das sollte helfen. Ich bin mir nicht sicher, ob diese Bibliothek auf allen Plattformen unterstützt wird, und ich weiß auch nicht, warum diese Funktionalität von dem Rest der IO Bibliothek getrennt. Mehr Infos hier: http://ruby-doc.org/stdlib/libdoc/ io / wait / rdoc /
Andere Tipps
Ich bin bereit, zu dem Schluss, dass keine, gibt es keine einfache Methode, dies zu tun. Per Vorschlag Peter Cooper, hier ist IO#ready_for_read?
:
class IO
def ready_for_read?
result = IO.select([self], nil, nil, 0)
result && (result.first.first == self)
end
end
Unter Windows habe ich einige Inkonsistenzen gesehen mit IO / wait . Der Rubin habe ich hier jetzt ist:
Rubin 1.9.2p136 (2010-12-25) [i386-mingw32]
Auf diese beide NREAD und bereit? umgesetzt werden, aber sie kehren zu fehlerhaften Ergebnissen. Auf einer anderen Version, die ich mit bereit? wurde noch gebrochen und NREAD nicht einmal existieren.
Eine Möglichkeit ist, verwenden io.stat.size , die die Anzahl der Bytes, erzählt in einem IO-Stream zu lesen. http://www.ruby-doc.org/core/classes/File /Stat.html
Die Dokumentation schlägt vor, dass es für Dateien, aber ich verwendet habe es an Rohren zu einem separaten Prozess verbunden (über Rubys Open3.popen3). Es ist so weit für mich gearbeitet.