2016-05-05 3 views
2

Ist es möglich, für read zuLesen von regulärer Datei: Blockieren oder weniger Daten zurückgeben?

  • Block
  • Rückkehr weniger Daten als
  • angefordert

, wenn sie von einer normalen Datei zu lesen, mit Ausnahme von

  • Anfrage mehr Daten als SSIZE_MAX
  • Lesen über EOF hinaus
  • Signal Interrupt

read(3) legt nahe, dass, mit Ausnahme der oben genannten Bedingungen, wenn read von einer normalen Datei liest, wird nie weniger Bytes zurückgeben als angefordert.

Der zurückgegebene Wert als nbyte weniger sein kann, wenn die Anzahl der Bytes in der Datei links weniger als nbyte ist, wenn der Lese() Anforderung durch ein Signal unterbrochen wurde, oder wenn die Datei ein Rohr oder FIFO oder spezielle Datei und hat weniger als nbyte Bytes sofort zum Lesen zur Verfügung.

Allerdings schlägt this answer eine hypothetische, in dem read weniger Bytes als angefordert zurückgeben kann, wenn der Kernel anderen I/O-Prioritäten zu setzen möchte. Während eine hypothetische, der Punkt ist, dass unter keinen Bedingungen gelesen werden kann erwartet, Rückgabe genau so viele Daten wie angefordert. So ist es nie sicher ist, auch wenn die drei oben genannten Bedingungen (SSIZE_MAX, EOF, Interrupt) nicht gelten, read auf eine normale Datei zu verwenden, ohne den Rückgabewert Überprüfung:

// all blockable signals have been ignored 
// 10 is guaranteed less than SSIZE_MAX 
// file size is known, access is locked 
if (read(fd_of_big_reg_file_with_zero_offset, buf, 10) < 0) { 
    // so all we have to do is handle errors 
} 

Außerdem habe ich noch nie erlebt ein Lesen Sie eine reguläre Datei, um zu blockieren, aber ich nehme an, dass es im Falle eines behebbaren E/A-Fehlers möglich ist, z. B. wenn ein fehlerhafter Block mehrere erneute Lesevorgänge erfordert.

+0

Ich kenne keine Situation, in der gelesen weniger Daten zurückgeben würde (außer den oben genannten). –

+3

Es gibt keine Fälle, in denen der Rückgabewert von 'read' nicht überprüft werden sollte. Außerdem hast du es rückwärts w.r.t. Blockierung. Lesen in der regulären Datei ALWAYS Blöcke, d. H. Es gibt keine Situation "kann nicht jetzt lesen, versuche es später erneut", die für nicht blockierendes IO charakteristisch ist. –

+1

Beachten Sie außerdem, dass "Ignorieren aller blockierbaren Signale" nicht bedeutet, dass der Systemaufruf nicht durch ein Signal unterbrochen werden kann. SIGSTOP kann nicht ignoriert oder blockiert werden, und SIGCONT würde danach den Prozess fortsetzen, auch wenn es ignoriert oder blockiert wird. Und je nach Signal-Semantik könnte dies eine "Lese" -Rückkehr mit einer kurzen Zählung bewirken. Also kann nichts, was Sie in Ihrem Programm tun können, diese Möglichkeit beseitigen. –

Antwort

3

Eine Möglichkeit, um einen kurzen Lesevorgang (zusätzlich zu den in Ihrer Frage genannten Fällen) zu erhalten, ist, wenn ein E/A-Fehler mitten in einem Lesevorgang auftritt.

Stellen Sie sich zum Beispiel vor, dass Sie eine reguläre Datei der Größe 1024 haben, die zwei 512-Byte-Sektoren belegt. Wie Ihnen nicht bekannt ist, ist der zweite Sektor schlecht und kann nicht gelesen werden. Wenn Sie die Datei öffnen und read(fd, buf, 1024) tun, wird 512 zurückgegeben und errno wird nicht festgelegt. Wenn Sie versuchen, erneut zu lesen, erhalten Sie einen Rückgabewert von -1 und errno = EIO.

Ich konnte dies unter Linux mit der error Funktion des Geräte-Mappers testen.

Da es nichts gibt, was Ihr Programm tun kann, um die Möglichkeit von E/A-Fehlern auszuschließen, bedeutet dies, dass niemals davon auszugehen ist, dass ein positiver Rückgabewert von read bedeutet, dass Sie so viele Bytes wie angefordert lesen .

+0

Es ist auch möglich, wenn auch implementierungsabhängig, ein kurzes Lesen zu erhalten, wenn der 'read()' Aufruf durch ein Signal unterbrochen wird, nachdem nur einige der angeforderten Daten übertragen wurden. –

+0

@AndrewHenle: In der Tat, aber OP hat das bereits erwähnt. –

+0

Aber jemand, der Ihre Antwort liest, sieht das vielleicht nicht. –