Finden Sie, wie viele Bytes aus einem FILE * oder einem Dateideskriptor gelesen werden können

8

Gibt es eine vorgegebene Möglichkeit, um zu sagen, wie viele Bytes zum Lesen bereit sind?

Gibt es eine FILE* oder einen Dateideskriptor?

Ich kann s=ftell(f),fseek(f,0,SEEK_END),e=ftell(f),fseek(f,s,SEEK_SET),e-s nicht verwenden, da FILE* nur einen Dateideskriptor umschließt, den ich von pipe(2) erhalten habe. , und ich bekomme ESPIPE , wenn ich das versuche.

Ich dachte daran, select(2) mit einem Null-Timeout zu verwenden, um zu sagen, dass ich mindestens ein Byte zum Lesen bereit habe und dann ein Byte nach dem anderen lese, bis die select(2) mir sagt, dass ich aufhören soll. Das scheint irgendwie klobig und langsam.

Gibt es einen besseren Weg, dies zu tun?

    
rampion 23.03.2011, 17:23
quelle

4 Antworten

6

read kann weniger Bytes zurückgeben, als Sie angefordert haben, und muss dies tun, wenn Daten verfügbar sind, aber es müsste blockiert werden, um den Puffer zu füllen.

Also ist es üblich, select zu verwenden, um lesbar zu erkennen und dann zu lesen, was auch immer Ihre bevorzugte Puffergröße ist. Alternativ setzen Sie O_NONBLOCK mit fcntl und prüfen Sie auf -1 Rückgabewert und errno EAGAIN.

    
Steve Jessop 23.03.2011, 17:44
quelle
4

Es ist nicht durch irgendwelche modernen Standards gesegnet, aber eine übliche traditionelle Unix-Methode, dies zu tun, ist mit ioctl(fd, FIONREAD, &n); Siehe die Antworten auf diese Frage:

Bestimmen Sie die Größe einer Pipe ohne Aufruf von read ()

    
R.. 23.03.2011 18:11
quelle
3

Wenn Sie nur nach etwas effizienterem suchen, das 1 Byte liest, und nicht nach der Größe der verfügbaren Daten im FIFO, dann können Sie:

  1. Setzen Sie den Dateideskriptor auf den nicht blockierenden Modus.
  2. Verwenden Sie select , um zu wissen, wann Daten verfügbar sind
  3. Rufen Sie read mit einem großen Puffer auf. Es gibt möglicherweise weniger zurück als angefordert ( überprüfen Sie den Rückgabecode ), oder es gibt -1 mit EAGAIN oder EWOULDBLOCK zurück, um anzuzeigen, dass Sie zum Aufruf von select zurückkehren sollen (keine Daten) verfügbar)
Thanatos 23.03.2011 17:46
quelle
0

Doy. fstat(2) . Ich habe es früher angeschaut und sah, dass es bei FILE* nicht funktionieren würde (weshalb ich auf das fseek -Anti-Muster zurückgefallen bin), dachte aber nicht daran, auf den Dateideskriptor zurückzugreifen.

    
rampion 23.03.2011 17:35
quelle

Tags und Links