In vielen Projekten habe ich gesehen, dass Datenobjekte / -strukturen im Binärmodus in eine Datei geschrieben werden und sie dann im Binärmodus wieder aus der Datei abrufen.
Ich frage mich, warum sie das im Binärmodus tun? Irgendwelche Leistungsunterschiede zwischen Text- und Binärmodus? Wenn nicht, wann dann binärer Modus oder Textmodus?
Binär ist schneller. Stellen Sie sich eine Ganzzahl vor, die in 32 Bits (4 Bytes) gespeichert ist, z. B. 123456. Wenn Sie dies als Binärdatei schreiben würden (wie es im Computer dargestellt wird), würde dies 4 Byte dauern (ignorieren der Abstände zwischen Elementen zur Ausrichtung in Strukturen) ).
Um die Zahl als Text zu schreiben, muss sie in eine Zeichenkette umgewandelt werden (einige Overhead zu konvertieren und Speicher zu speichern) und dann ausgeschrieben werden, es dauert mindestens 6 Bytes, da 6 Zeichen zur Verfügung stehen die Nummer. Dies umfasst keine zusätzlichen Füllzeichen wie Leerzeichen für die Ausrichtung oder Trennzeichen zum Lesen / Trennen der Daten.
Nun, wenn man bedenkt, dass man mehrere tausend Elemente hat, kann sich die zusätzliche Zeit summieren und mehr Speicherplatz beanspruchen, was länger zum Einlesen braucht, und dann gibt es die zusätzliche Zeit, um nach dem Speichern wieder in Binär zu konvertieren lies den Wert in den Speicher.
Der Vorteil für Text ist, dass es für Personen viel einfacher zu lesen ist, als zu versuchen, Binärdaten oder Hex-Dumps der Daten zu lesen.
Wenn Ihr Programm das einzige Programm ist, das die Datei verwenden wird, können Sie interne Strukturen "so wie sie sind" mit Binärdateien speichern.
Wenn Sie jedoch die Dateien mit anderen Programmen oder über das Internet austauschen möchten, sind Binärformate nicht so gut. Denken Sie zum Beispiel an das Problem mit big-endian vs. little-endian Maschinen. Außerdem hat der Empfänger der Dateien oder Daten höchstwahrscheinlich keinen Zugriff auf Ihren Code und Ihre Strukturen, so dass ein textbasiertes Format leichter zu analysieren und in eigene Strukturen zu implementieren ist.
Bei der Leistung stimmt es, dass Sie Ihre internen Strukturen direkt lesen und schreiben können, weil Sie sie nicht (auch als Marshalling bezeichnet) in ein anderes Format übersetzen müssen.
In der Vergangenheit sollte der binäre Modus mehr oder weniger transparenten Zugriff bieten
zum zugrundeliegenden Strom; Textmodus "normalisiert" sich zu einem Standardtext
Darstellung, bei der Zeilen durch die einzelne '\n'
beendet werden
Charakter. Darüber hinaus kann das System Beschränkungen für die Größe auferlegen
einer Binärdatei, beispielsweise indem sie erfordert, dass sie ein Vielfaches von 128 oder
512 Bytes. (Der erste war der Fall von CP / M, der zweite von vielen der
DEC OS.) Textdateien haben diese Einschränkung nicht, und in Fällen, in denen
das Betriebssystem auferlegt es, die Bibliothek wird in der Regel eine zusätzliche einführen
Dateiendezeichen für Textdateien. (Noch heute, die meisten Windows
Bibliotheken erkennen das alte CP / M-Ende der Datei, 0x1A, beim Einlesen von Text
Modus.) Wegen dieser Erwägungen wird Textmodus nur über definiert
ein begrenzter Satz von Binärwerten. (Aber wenn Sie 200 Bytes in eine Binärdatei schreiben
Datei, erhalten Sie 256 oder 512 zurück, wenn Sie es erneut lesen. Historisch,
binary sollte nur für Text verwendet werden, der ansonsten strukturiert ist, also
dass Sie das logische Ende erkennen und diese zusätzlichen ignorieren können
Bytes.)
Sie können auch ziemlich willkürlich in einer binär geöffneten Datei suchen Modus; Sie können nur zum Anfang oder zu einer Position, die Sie haben, suchen zuvor im Textmodus gespeichert. (Dies ist, weil die Zeile endet Mappings bedeuten, dass es keine einfache Beziehung zwischen der Position gibt in der Datei und die Position im Textstrom.)
Beachten Sie, dass dies orthogonal zu der Frage ist, ob die Ausgabe formatiert ist oder nicht:
Wenn Sie mit <<
ausgeben (und mit >>
eingeben), wird das IO formatiert,
unabhängig davon, in welchem Modus die Datei geöffnet wurde. Und die Formatierung
ist immer Text; Die Iostreams sind entworfen, um Ströme von zu manipulieren
Text, und haben nur begrenzte Unterstützung für die Eingabe und Ausgabe von Nicht-Text.
Heute hat sich die Situation etwas geändert: In vielen Fällen erwarten wir was wir schreiben, um von anderen Maschinen lesbar zu sein, was einen Brunnen voraussetzt definiertes Format, das möglicherweise nicht das nativ verwendete Format ist. (Also, für Beispiel: Das Internet erwartet die zwei Bytefolgen 0x0D, 0x0A als Zeile Ende, was anders ist als das, was intern in Unix und vielen verwendet wird andere Betriebssysteme.) Wenn Portabilität ein Problem ist, definieren Sie im Allgemeinen ein Formatieren Sie es, schreiben Sie es explizit und verwenden Sie den binären Modus, um sicherzustellen, dass was Sie tun schreiben ist genau das was geschrieben wird; Ähnlich bei der Eingabe verwenden Sie binär formatieren und die Konventionen manuell behandeln. Wenn du nur schreibst eine lokale Festplatte, die nicht freigegeben ist, jedoch Textmodus ist in Ordnung, und ein bisschen weniger Arbeit.
Auch dies gilt für Text. Wenn du ein binäres Format willst, du
muss den binären Modus verwenden, aber das ist bei weitem nicht ausreichend. Du wirst es müssen
Implementieren Sie alle formatierten IO selbst. In solchen Fällen, ich generell
Verwenden Sie nicht std::istream
oder std::ostream
(deren Abstraktion Text ist),
sondern definiere meine eigenen Stream-Typen, abgeleitet von std::ios_base
(für die Fehlerbehandlungskonventionen) und std::streambuf
verwenden (für
die physische IO).
Vergessen Sie schließlich nicht, dass all IO in einigen formatiert ist Weise. Nur einen Speicherblock in die Datei zu schreiben bedeutet, dass der Format ist, was auch immer die aktuelle Implementierung Ihnen gibt (welche ist in der Regel nicht dokumentiert, was bedeutet, dass Sie wahrscheinlich nicht in der Lage sein werden um es in der Zukunft zu lesen). Wenn alles, was Sie tun, auf die Festplatte verschüttet wird, und das einzige Mal, dass Sie es lesen, ist mit dem gleichen Programm, mit dem kompiliert die gleiche Version des gleichen Compilers, mit den gleichen Compiler-Optionen, dann Sie können Speicher nur auslagern, vorausgesetzt, der betreffende Speicher besteht nur aus PODs. und enthält keine Zeiger. Ansonsten müssen Sie definieren (und dokumentieren) das Format, das Sie verwenden, und implementieren Sie es. In solchen Fällen würde ich vorschlagen, zu verwenden ein existierendes Format, wie XDR, anstatt dein eigenes zu erfinden: es ist eine Menge einfacher zu schreiben "verwendet XDR-Format" als Dokumentation, anstatt Beschreibung des tatsächlichen Bit- und Byte-Layouts für alle verschiedenen Typen.
Wenn Sie eine Datei in einem Textmodus lesen / schreiben, arbeiten Sie mit Text. Es könnte ein Thema von Codierungsfehlern und OS-spezifischen Formatänderungen sein, obwohl es manchmal gut funktionieren kann. Im Binärmodus werden Sie diese Einschränkungen jedoch nicht erfüllen. Außerdem kann der Textmodus komische Dinge mit \n
-Zeichen machen, zum Beispiel durch \n\r
ersetzen.
Fopen Verweis zum Beispiel sagt:
Im Fall von Textdateien, abhängig von der Umgebung, in der der Anwendung läuft, einige Sonderzeichen Umwandlung kann auftreten in Eingabe- / Ausgabeoperationen, um sie an eine systemspezifische Textdatei anzupassen Format. In vielen Umgebungen, wie den meisten UNIX-basierten Systemen, ist dies der Fall Es macht keinen Unterschied, eine Datei als Textdatei oder als Binärdatei zu öffnen. Beide werden genau gleich behandelt, aber Differenzierung ist empfohlen für eine bessere Portabilität.
Nur wenige Betriebssysteme sind von der Wahl zwischen Binär- und Textmodus betroffen. Keines der Unix- oder Linux-Systeme macht etwas Spezielles für den Textmodus - das heißt, der Text ist derselbe wie der Binärcode.
Insbesondere Windows und VMS transformieren Daten im Textmodus. Windows wandelt \n
in \r\n
um, wenn in eine Datei geschrieben wird und umgekehrt beim Lesen. VMS hat eine zu beobachtende Dateiaufzeichnungsstruktur, also übersetzt es im Standardmodus \n
in einen Datensatzbegrenzer.
Wo es anders ist, binär ist schneller. Wenn es nicht anders ist, macht es keinen Unterschied.
Im binären Modus haben Sie eine Byte-Größe (256) und im Text-Modus kaum mehr als 100 Zeichen. Offensichtlich werden Sie mehr als doppelt so groß für das Speichern von Daten sein. Darüber hinaus gibt es Fälle, in denen Sie sich an die Strukturspezifikation wie ein Netzwerkpaket wie IPv4 halten müssen.
Nehmen wir ein Beispiel
%Vor%Ist es nicht schwierig, Bitfelder im Textmodus zu speichern? Offensichtlich werden Sie so viele Dinge verlieren.
Sie können jedoch Datenobjekte im Textformat speichern, wie es mit MIME gemacht wurde, aber es wird eine zusätzliche Routine benötigt, um im Binärmodus zu konvertieren; Leistung gehämmert.