Ich arbeite an einem Problem in Programming Pearls - speziell an der Implementierung eines Programms, das eine Datei sortiert, die höchstens 10.000.000 Ganzzahlen enthält (Spalte 1, Problem 3). Da im Buch nicht angegeben ist, wie die Daten in der Datei gespeichert werden sollen, erwäge ich, die Ganzzahlen als unformatierte Bytes zu speichern (es gibt einige andere Einschränkungen, die unformatierte Bytes zu einer guten Option machen). Ich habe noch nie auf einem so niedrigen Niveau gearbeitet, also möchte ich wissen, ob es etwas Gefährliches gibt, auf das ich achten sollte. Muss ich mir zum Beispiel Sorgen machen, wenn ich versehentlich eine Dateiendesequenz verwende, wenn ich rohe Bytes in eine Datei schreibe?
Bearbeiten:
Mir ist jetzt klar, wie umfassend meine Frage war. Ich meinte wirklich Probleme der katastrophaleren Art, wie das versehentliche Überschreiben anderer Dateien auf der Festplatte. Entschuldigung, ich war ursprünglich nicht klarer.
Antworten:
Die einzige Gefahr, der Sie begegnen werden, ist Little vs. Big Endianess (ob das höchst- oder niedrigstwertige Byte zuerst geschrieben wird). Wenn Sie sich jedoch in derselben Umgebung befinden, tritt kein Problem auf. Neben der allgemeinen Sicherstellung des Schreibens / Parsens von Roundtrip.
Das Dateisystem ist für die Verarbeitung beliebiger Bytefolgen ausgelegt.
quelle
Nein, tatsächlich funktionieren so viele Dateiformate. Häufige Beispiele für solche Binärdateien sind Bilder und Musik- / Audiodateien.
Befolgen Sie die folgenden Richtlinien, um die Integrität der Datei und der daraus gelesenen Daten zu gewährleisten:
Die spezifischen Details variieren je nach Framework, Plattform und Sprache. Dies sollte jedoch die grundlegenden "Fallstricke" mit Datei-E / A abdecken.
quelle
int
kann ein Wert irgendwo zwischen 2 und 8 oder mehr Bytes liegen (eigentlich Oktette).int
auf zwei verschiedenen Maschinen unterschiedliche Datentypen berücksichtigt werden können.Wenn Sie nicht nur Daten in einem vorhandenen Format lesen und schreiben, sondern auch ein neues Binärdateiformat erstellen möchten, müssen Sie zusätzlich zu allen bereits erwähnten Fallbeispielen unbedingt einen Dateikopf einfügen : einen Datenblock am Anfang der Datei, die das Dateiformat eindeutig identifiziert und alle erforderlichen Metadaten aufzeichnet.
Gute Datei-Header enthalten mindestens drei Dinge:
Eine " magische Zahl " von mindestens vier Bytes. Die magische Zahl MUSS rfc2119 die allerersten N Bytes in der Datei sein, MUSS niemals für ein anderes Dateiformat verwendet worden sein, das Sie ausgraben können, und MUSS mindestens ein Byte enthalten, das kein druckbares ASCII-Zeichen ist. In der PNG-Spezifikation erfahren Sie, wie Sie eine wirklich gründliche magische Zahl entwerfen . Im Quellcode des
file(1)
Befehls finden Sie eine Datenbank mit vorhandenen magischen Zahlen, die so umfassend ist, wie Sie wahrscheinlich finden.Der Sinn einer magischen Zahl besteht darin, die Datei bandintern mit ihrem Format eindeutig zu kennzeichnen. Wenn Sie keine magische Zahl angeben oder dies nicht das allererste Mal in der Datei ist, besteht die Gefahr, dass Programme Ihre Datei fälschlicherweise als einen anderen Dateityp identifizieren , was zu Datenverlust, Viren, die nicht erkannt werden , und anderem führt Katastrophen.
Eine Angabe der Version des Dateiformats. Auch wenn Sie der Meinung sind, dass Sie Ihr Dateiformat niemals drastisch überarbeiten müssen, sollten Sie die nächsten zwei Bytes nach der magischen Zahl eingeben
00 00
und dokumentieren, dass dies eine 16-Bit-Versionsnummer in einer bestimmten Endianität ist (je nachdem, was Sie möchten, aber wählen Sie one und bleibe dabei in der gesamten Datei ) und wird inkrementiert, wenn sich die Bedeutung der nachfolgenden Daten radikal ändert. Dein zukünftiges Ich wird es dir danken.(Die PNG-Spezifikation schlägt hier einen anderen Weg ein und legt fest, dass Chunk-Formate eingefroren werden und dass alle zukünftigen Änderungen am Format die Form neuer Chunk-Typen annehmen. Dies gilt auch, ich empfehle jedoch den einfachen Magic Number + Versionsnummer-Ansatz für Anfänger in der Verarbeitung binärer Daten. Die Leute, die PNG entwickelt haben, haben auf jahrzehntelange Erfahrung mit Bildformaten zurückgegriffen.)
Eine Art Mechanismus zum Einbetten beliebiger Metadaten in die Datei. Dies kann so einfach sein, dass die nächsten zwei Bytes ein 16-Bit-Versatz vom Ende des Headers bis zum Beginn der eigentlichen Daten sind, wobei alles dazwischen als UTF-8-Schlüssel-Wert-Paare nach RFC 822 interpretiert wird (das heißt, "
Tag: value\n
" - wenn Sie diese Route wählen, empfehle ich, das Falten langer Linien nicht zuzulassen). Auch hier ist PNG wesentlich cleverer.quelle
Unterschiedliche Architekturen haben unterschiedliche Darstellungen für ganze Zahlen. Das Hauptrisiko ist hier das Speichern der Byte - Darstellung einer ganze Zahl in einer Maschine und dann das zurück zu lesen versuchen , und den Inhalt als ganze Zahlen interpretieren in Maschine B. Wenn Maschinen A und B verschiedene Größen für ganze Zahlen und / oder unterschiedliche Endian , Sie‘ lle verursachen höchstwahrscheinlich undefiniertes Verhalten (z. B. in C) oder eine Ausnahme.
Da dies nur ein Programmierbeispiel und kein "echtes" Programm ist, ist es nicht wirklich ein Problem. Wenn dies ein echtes Programm wäre, wäre es normalerweise keine gute Idee, ein eigenes anwendungsspezifisches Binärformat zu rollen. Es gibt bessere Lösungen wie SQLite oder auf Zeichenfolgen basierende Serialisierungsformate wie JSON, YAML, XML usw. Für einzelne Werte würde es ausreichen, sie in eine Zeichenfolge umzuwandeln. Für einfache Listen können Sie eine Zeichenfolge pro Zeile speichern und die Eingabe in Zeilenumbrüche aufteilen, wenn Sie sie wieder einlesen.
quelle