Was ist der Grund für fread / fwrite Mitnahmen Größe und zählen als Argumente?

StackOverflow https://stackoverflow.com/questions/295994

  •  08-07-2019
  •  | 
  •  

Frage

Wir hatten eine Diskussion hier bei der Arbeit in Bezug auf, warum fread und eine Größe pro Mitglied nehmen fwrite und zählt und gibt die Anzahl der Mitglieder gelesen / geschrieben, anstatt nur einen Puffer und Größe nehmen. Die einzige Verwendung für sie uns tun konnten, ist, wenn Sie lesen wollen / schreiben eine Reihe von Strukturen, die nicht teilbar durch die Plattform ausgerichtet sind und damit aufgefüllt haben, aber das kann nicht so verbreitet sein wie diese Wahl zu rechtfertigen im Design.

Von FREAD (3) :

  

Die Funktion fread () nmemb Elemente der Daten liest, die Bytes jeder Größe lang,   aus dem Strom, auf den Strom, so dass sie an der Stelle zu speichern gegebenen   von ptr.

     

Die Funktion fwrite () schreibt nmemb Elemente von Daten, die jeweils eine Größe bytes   lang, auf den Strom, auf den Strom, so dass sie von dem Ort zu erhalten   gegeben durch ptr.

     

fread () und fwrite () gibt die Anzahl der Elemente erfolgreich gelesen oder geschrieben   (Das heißt, nicht die Anzahl der Zeichen). Wenn ein Fehler auftritt, oder die   End-of-Datei erreicht ist, ist der Rückgabewert eine kurze Elementanzahl (oder Null).

War es hilfreich?

Lösung

Es basiert auf, wie fread implementiert wird.

Die Single UNIX Specification sagt

  

Für jedes Objekt, Größe Anrufe müssen sein   hergestellt zum fgetc () -Funktion und die   Ergebnisse gespeichert sind, in der Reihenfolge gelesen, in   ein Array von unsigned char genau   die über das Objekt.

fgetc hat auch diese Notiz:

  

Da fgetc () auf Bytes arbeitet,   Lesen eines Zeichens, bestehend aus   mehrere Bytes (oder „ein Multi-Byte-   Zeichen ") können mehrere Anrufe erfordern   fgetc ().

Natürlich ist diese früher ausgefallene Variable-Byte-Zeichencodierungen wie UTF-8.

Der SUS stellt fest, dass dies tatsächlich der ISO C Dokumente entnommen wird.

Andere Tipps

Der Unterschied in fread (buf, 1000, 1, Bach) und fread (buf, 1, 1000, Strom) ist, dass im ersten Fall erhalten Sie nur ein Stück von 1000 Bytes oder nuthin, wenn die Datei kleiner ist und im zweiten Fall, dass Sie alles, was in der Datei bekommen weniger als und bis zu 1000 Bytes.

Das ist reine Spekulation, aber in den Tagen (Einige sind immer noch rund) viele Dateisysteme auf einer Festplatte nicht einfach Bytestreams waren.

Viele Dateisysteme wurden Datensatz basiert, so dass solche Dateisysteme auf effiziente Weise gerecht zu werden, werden Sie die Anzahl der Elemente ( „Aufzeichnungen“) angeben müssen, so dass Fwrite / fread auf dem Speicher als Datensätze zu betreiben, nicht nur Byte-Streams.

Hier, lassen Sie mich diese Funktionen beheben:

size_t fread_buf( void* ptr, size_t size, FILE* stream)
{
    return fread( ptr, 1, size, stream);
}


size_t fwrite_buf( void const* ptr, size_t size, FILE* stream)
{
    return fwrite( ptr, 1, size, stream);
}

Als eine Begründung für die Parameter / fread() fwrite(), ich habe meine Kopie von K & R lange verloren vor, so kann ich nur raten. Ich denke, dass eine wahrscheinliche Antwort ist, dass Kernighan und Ritchie kann einfach gedacht, dass binäre I / O ausgeführt wird am natürlichsten auf Arrays von Objekten durchgeführt werden würde. Auch können sie gedacht, dass Block-I / O wäre schneller / einfacher zu implementieren oder was auch immer auf einigen Architekturen.

Auch wenn der C-Standard legt fest, dass fread() und fwrite() in Bezug auf fgetc() und fputc() umgesetzt werden, denken Sie daran, dass der Standard entstand lange nach C von K & R definiert wurde und dass die Dinge in der Norm festgelegte könnten im Original nicht gewesen Designer Ideen. Es ist sogar möglich, dass die Dinge, die in K & R „The C Programming Language“ ist vielleicht nicht das gleiche sein, wie wenn die Sprache zuerst entworfen wurde.

Schließlich ist hier, was P. J. Plauger über fread() in "The Standard C Library" zu sagen hat:

  

Wenn die size (zweite) Argument größer als eins ist, kann man nicht bestimmen   ob die Funktion auch gelesen, bis über zusätzliche Zeichen size - 1, was es berichtet.   In der Regel sind Sie besser dran Aufruf der Funktion als statt fread(buf, 1, size * n, stream);   fread(buf, size, n, stream);

Bascially, er sagt, dass fread() der Schnittstelle defekt ist. Für fwrite() stellt er fest, dass „Schreibfehler im Allgemeinen selten ist, so ist dies kein großes Manko.“ - eine Aussage, die ich würde nicht zustimmen

Wahrscheinlich geht es zurück auf die Art und Weise, die Datei-I / O umgesetzt wurde. (Zurück in den Tag) Es könnte schneller gewesen zu schreiben / lesen, um Dateien in Blöcke dann alles zu schreiben, auf einmal.

Ich denke, es liegt daran, dass C-Funktion Überlastung fehlt. Wenn es etwas ist, würde Größe überflüssig. Aber in C können Sie keine Größe eines Array-Elements bestimmen, müssen Sie eine angeben.

Bedenken Sie:

int intArray[10];
fwrite(intArray, sizeof(int), 10, fd);

Wenn Fwrite akzeptierte Anzahl von Bytes, könnten Sie schreiben folgende:

int intArray[10];
fwrite(intArray, sizeof(int)*10, fd);

Aber es ist nur ineffizient. Sie sizeof (int) mal mehr Systemaufrufe haben.

Ein weiterer Punkt, in Betracht taked werden soll, ist, dass Sie in der Regel in eine Datei geschrieben wird, nicht ein Teil eines Array-Elements sollen. Sie wollen die ganze Zahl oder nichts. fwrite gibt eine Reihe von Elementen erfolgreich geschrieben. Also, wenn Sie, dass nur 2 Low-Byte eines Elements entdecken, was geschrieben wird, würden Sie tun?

Auf einigen Systemen (aufgrund Ausrichtung) Sie nicht ein Byte einer ganzen Zahl zugreifen können, ohne eine Kopie und Verschiebung zu schaffen.

Mit getrennte Argumente für Größe und Zählung könnte auf eine Implementierung von Vorteil sein, dass alle Teilaufzeichnungen Lesen vermeiden. Wenn man Single-Byte verwenden, von so etwas wie ein Rohr liest, auch wenn man wurde festFormatDaten verwendet wird, würde man die Möglichkeit eines Datensatzes immer aufgeteilt auf zwei liest ermöglichen haben. Wenn könnte stattdessen fordert z.B. ein nicht-blockierenden Schreib- von bis zu 40 Datensätze von 10 Byte je, wenn es 293 Bytes zur Verfügung steht, und hat das System Return 290 Bytes (29 ganz Datensätze) während 3 Bytes bereit für die nächste Lese verlassen, das wäre viel bequemer.

Ich weiß nicht, inwieweit Implementierungen von fread solche Semantik umgehen kann, aber sie konnten sicher auf Implementierungen praktisch sein, sie zu unterstützen versprechen könnte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top