Ich erstelle ein proprietäres Dateiformat für eine Anwendung, die ich in C # .NET geschrieben habe, um gespeicherte Informationen und möglicherweise Projektressourcen zu speichern. Gibt es einen Standard, wie dies in irgendeiner Weise zu tun ist? Ich ging einfach zu Serialize
meinen Objekten in die Binärdatei und erstellte einen Header, der mir sagte, wie ich die Datei analysieren sollte. Ist das ein schlechter Ansatz?
c#
.net
file-structure
corylulu
quelle
quelle
BinaryFormatter
.Antworten:
Am einfachsten ist es wahrscheinlich, Ihre Struktur mithilfe der
XMLSerializer
Klasse in XML zu serialisieren . Sie müssten wahrscheinlich keine separate Header- und Body-Struktur erstellen, sondern alle Assets in XML serialisieren. Auf diese Weise können Sie Ihre Dateistruktur problemlos außerhalb Ihres eigenen Programms überprüfen / bearbeiten und sind einfach zu verwalten.Wenn Ihre Dateistruktur jedoch sehr komplex ist und viele verschiedene Assets unterschiedlichen Typs enthält, sodass die Serialisierung der gesamten Struktur in XML zu aufwändig ist, sollten Sie die einzelnen Assets separat serialisieren und mithilfe der
Packaging
Bibliothek in C # zu einem einzigen Paket kompilieren. . Auf diese Weise werden im Wesentlichen DOCX-, XSLX-, PPTX- und andere Office-Dateiformate erstellt.quelle
protobuf-net
um meine Daten zu serialisieren und das funktioniert großartig. Aber ich muss Stücke separat serialisieren, damit das, worüber Sie mit der Verpackungsbibliothek sprechen, genau das ist, was ich brauche.Von jemandem, der viele Dateiformate analysieren musste, habe ich eine andere Meinung als die meisten anderen.
Machen Sie die magische Zahl sehr einzigartig, damit die Dateiformaterkenner anderer Formate sie nicht als Ihre identifizieren. Wenn Sie Binär verwenden, weisen Sie der magischen Zahl am Anfang eines Binärformats 8 oder 16 zufällig generierte Bytes zu. Wenn Sie XML verwenden, weisen Sie einen geeigneten Namespace in Ihrer Domain zu, damit er nicht mit anderen Personen in Konflikt gerät. Wenn Sie JSON verwenden, hilft Ihnen Gott. Vielleicht hat jemand schon eine Lösung für diesen Gräuel eines Formats gefunden.
Planen Sie die Abwärtskompatibilität. Speichern Sie die Versionsnummer des Formats so, dass spätere Versionen Ihrer Software mit Unterschieden umgehen können.
Wenn die Datei groß sein kann oder Teile davon vorhanden sind, die aus irgendeinem Grund übersprungen werden sollen, stellen Sie sicher, dass es eine gute Möglichkeit gibt, dies zu tun. XML, JSON und die meisten anderen Textformate sind dafür besonders schrecklich, da sie den Leser zwingen, alle Daten zwischen dem Start- und dem Endelement zu analysieren, auch wenn sie sich nicht darum kümmern. EBML ist etwas besser, da es die Länge der Elemente speichert, sodass Sie bis zum Ende überspringen können. Wenn Sie ein benutzerdefiniertes Binärformat erstellen, gibt es ein weit verbreitetes Design, in dem Sie als Erstes eine Blockkennung und eine Länge in der Kopfzeile speichern. Anschließend kann der Leser den gesamten Block überspringen.
Speichern Sie alle Zeichenfolgen in UTF-8.
Wenn Sie Wert auf langfristige Erweiterbarkeit legen, speichern Sie alle Ganzzahlen in einer Form mit variabler Länge.
Prüfsummen sind nett, weil sie es dem Leser ermöglichen, ungültige Daten sofort abzubrechen, anstatt möglicherweise in Abschnitte der Datei zu gelangen, die zu verwirrenden Ergebnissen führen können.
quelle
Nun, es gibt Zeiten, in denen das, was Sie beschreiben, ein sehr schlechter Ansatz sein kann. Dies wird vorausgesetzt, wenn Sie "serialisieren" sagen, dass Sie die Fähigkeit einer Sprache / eines Frameworks verwenden, ein Objekt einfach zu nehmen und direkt in eine Art Binärstrom auszugeben. Das Problem ist, dass sich die Klassenstrukturen im Laufe der Jahre ändern. Können Sie eine in einer früheren Version Ihrer App erstellte Datei erneut laden, wenn sich alle Ihre Klassen in einer neueren ändern?
Um die Langzeitstabilität eines Dateiformats zu gewährleisten, ist es besser, jetzt die Ärmel hochzukrempeln und Ihre eigenen Serialisierungs- / Streaming-Methoden innerhalb Ihrer Klassen zu schreiben. dh manuelles Schreiben von Werten in einen Stream. Schreiben Sie eine Kopfzeile, während Sie angeben, dass die Formatversion beschrieben wird, und speichern Sie dann die Daten in der gewünschten Reihenfolge. Auf der Leseseite wird der Umgang mit verschiedenen Versionen des Dateiformats viel einfacher.
Die andere Option ist natürlich XML oder JSON. Nicht unbedingt die beste für binäre, schwere Inhalte, aber einfach und für den Menschen lesbar ... ein großes Plus für die langfristige Lebensfähigkeit.
quelle
Ich würde auch gerne Antworten auf diese Frage von Leuten hören, die mehr Erfahrung als ich haben.
Ich habe persönlich mehrere Dateiformate für meine Arbeit implementiert und bin zu einem XML-Dateiformat übergegangen. Meine Anforderungen und die Hardware, mit der ich interagiere, ändern sich ständig, und es ist nicht abzusehen, was ich dem Format in Zukunft hinzufügen muss. Einer der Hauptvorteile von XML besteht darin, dass es halbstrukturiert ist . Aus diesem Grund vermeide ich im Allgemeinen die automatische XML-Serialisierung, die .NET bereitstellt, da ich der Meinung bin, dass ein genaues Format erwartet wird.
Mein Ziel war es, ein XML-Format zu erstellen, mit dem in Zukunft neue Elemente und Attribute hinzugefügt werden können und die Reihenfolge der Tags nach Möglichkeit keine Rolle spielt. Wenn Sie sicher sind, dass Sie Ihre gesamte Datei in den Speicher laden können, ist XPATH wahrscheinlich eine gute Wahl.
Wenn Sie es mit besonders großen Dateien zu tun haben oder die Datei aus anderen Gründen nicht auf einmal laden können, müssen Sie wahrscheinlich einen XmlStreamReader verwenden, um nach bekannten Elementen zu suchen und diese Elemente mit ReadSubtree erneut zu durchsuchen und erneut zu scannen ...
quelle