Frage

Ich muss in der Lage sein, einige Daten in einem benutzerdefinierten Binärdateiformat zu speichern.Ich habe noch nie ein eigenes Dateiformat entworfen.Es muss ein benutzerfreundliches Format für den Austausch zwischen den Welten C#, Java und Ruby/Perl/Python sein.

Zunächst besteht die Datei aus Datensätzen.Ein GUID-Feld und ein JSON/YAML/XML-Paketfeld.Ich bin nicht sicher, was ich als Trennzeichen verwenden soll.Ein Komma, ein Tabulator oder ein Zeilenumbruch scheinen zu zerbrechlich zu sein.Was macht Excel?oder die OpenOffice-Formate vor XML?Sollten Sie die ASCII-Zeichen 0 oder 1 verwenden?Ich weiß nicht, wo ich anfangen soll.Gibt es Artikel oder Bücher zum Thema?

Dieses Dateiformat kann später um einen „Header-Abschnitt“ erweitert werden.

Notiz:Zunächst werde ich in .NET arbeiten, aber ich möchte, dass das Format leicht portierbar ist.

AKTUALISIEREN:
Die Verarbeitung der „Pakete“ kann langsam sein, die Navigation innerhalb des Dateiformats jedoch nicht.Daher denke ich, dass XML vom Tisch ist.

War es hilfreich?

Lösung

Ich werde versuchen, einige allgemeine Hinweise zum Erstellen eines portablen Binärdateiformats hinzuzufügen.

Beachten Sie, dass die Erfindung eines binären Dateiformats bedeutet, zu dokumentieren, wie die darin enthaltenen Bits aussehen müssen und was sie bedeuten.Es geht nicht um Codierung, sondern um Dokumentation.

Nun die Hinweise:

  1. Entscheiden Sie, was Sie damit machen möchten Endianess.Ein guter und einfacher Weg ist, es ein für alle Mal zu entscheiden.Die Wahl wäre vorzugsweise Little Endian, wenn es auf einem gewöhnlichen PC (d. h. x86) verwendet wird, um Konvertierungen (Leistung) zu sparen.

  2. Erstellen Header.Ja, es ist eine gute Idee, immer eine Kopfzeile zu haben.Die ersten Bytes der Datei sollten Ihnen sagen können, mit welchem ​​Format Sie es zu tun haben.

    • Beginnen Sie mit Magie, um Ihr Format erkennen zu können (ASCII-String reicht aus)
    • Version hinzufügen.Das Hinzufügen einer Version Ihres Dateiformats kann nicht schaden und ermöglicht Ihnen später die Abwärtskompatibilität.
  3. Fügen Sie abschließend die Daten hinzu.Jetzt ist das Format der Daten spezifisch und basiert immer auf Ihren genauen Anforderungen.Grundsätzlich werden die Daten in einem Binärbild einer Datenstruktur gespeichert.Die Datenstruktur ist das, was Sie sich ausdenken müssen.

Wenn Sie über bestimmte Indizes wahlfreien Zugriff auf Ihre Daten benötigen, B-Bäume sind der richtige Weg. Wenn Sie jedoch nur viele Zahlen benötigen, um sie alle zu schreiben und dann alle zu lesen, reicht ein „Array“ aus.

Darüber hinaus könnten Sie a verwenden TLV (Typ-Länge-Wert) Konzept für Vorwärtskompatibilität.

Andere Tipps

Wie wäre es mit Blick auf „Protokollpuffer“? Konzipiert als ein effizienten, portable Version tolerante Allzweck-Binärformat, es gibt Ihnen C ++, Java und Python in dem google-Bibliothek und C #, Perl, Ruby und andere in der Community Ports

Beachten Sie, dass Guid keinen spezifischen Datentyp hat, aber Sie können es als eine Nachricht mit (im Wesentlichen) Shim eines byte[].

Normalerweise für .NET Arbeit, ich würde empfehlen, protobuf- net (aber als Autor, bin ich etwas voreingenommen) - aber wenn Sie später andere Sprachen verwenden möchten, könnten Sie besser (langfristig) tun Jons dotnet-protobufs ; das wird Ihnen eine vertraute API auf der anderen Plattformen (wo-wie protobuf-net verwendet .NET Idiome).

ASCII Zeichen 0 oder 1 nehmen jeweils mehrere Bits auf (wie jedes andere Zeichen), also, wenn Sie es so zu speichern, dass Ihre „binäre“ Datei mehrere Male größer sein wird, als es sein sollte. Bei Textdatei von Nullen und Einsen ist nicht gerade eine Binärdatei:)

Sie können das Binary schreiben Rohdaten direkt an einen Datei-Stream . Der einzige Teil, den Sie brauchen, um herauszufinden, ist das Übersetzen Ihrer In-Memory-Format (in der Regel eine Art von Objektgraph) in eine Byte-Sequenz, die die Binary verbrauchen kann.

Jedoch , wenn Ihr primäres Interesse Portabilität ist, empfehle ich gegen ein binäres Format überhaupt. XML ist entworfen, um die Portabilität und Interoperabilität Problem zu lösen. Es ist ausführlich und gewichtig als Dateiformat, aber das ist die Trade-off Sie diese Probleme für Sie lösen machen zu bekommen Wenn ein lesbares Format vom Tisch ist, Marc Antwort ist der Weg zu gehen. Keine Notwendigkeit, das Portabilität Rad neu zu erfinden!

Es hängt davon ab, welche Art von Daten werden Sie in die binären Datei schreiben und was ist der Zweck der Binärdatei. Sind sie Klassenobjekt oder nur Aufzeichnungsdaten? Wenn es Aufzeichnungsdaten würde ich empfehlen, im XML-Format zu setzen. So können Sie eine Schema-Validierung umfassen kann bestätigen, dass die Datei mit Ihnen Standards entspricht. Es gibt Tools in Java und .NET zu importieren und exportieren Daten aus / in XML-Format.

Angenommen, Ihr Format ist:

    struct Format
    {
        struct Header // 1
        {
            byte a;
            bool b1, b2, b3, b4, b5, b6, b7, b8;
            string name;
        }
        struct Container // 1...*
        {
            MyTypeEnum Type;
            byte[] data;
        }
    }

    enum MyTypeEnum
    {
        Sound,
        Video,
        Image
    }

Dann würde ich eine sequentielle Datei mit:


Byte // a

Byte // b

int // Name Größe

char [] // Name (was die Größe oben angegeben hat, daran denkt, ein Zeichen ist 16 Bits in .NET)

int // MyTypeEnum Typ

int // Datengröße

byte [] // Daten (die die Größe oben angegeben hat)


Dann können Sie die letzten drei Zeilen wiederholen, so viele, wie Sie wollen.

Zum Lesen Sie die BinaryReader verwenden, die Unterstützung hat für das Lesen von Bytes, ganze Zahlen und eine Reihe von Bytes. Es gibt auch eine BinaryWriter.

Ferner daran erinnern, dass Microsoft .NET (also auf einer Windows / Intel-Maschine) ist Little-Endian. So ist die BinaryReader und BinaryWriter.

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