C#.NETで記述したアプリケーション用に独自のファイル形式を作成して、保存情報を保存し、おそらくプロジェクトの資産を保存します。何らかの方法でこれを行う方法の基準はありますか?私は単純に行っていたSerialize
バイナリに私のオブジェクトとどのようにファイルを解析するために私に言うだろうヘッダを作成します。これは悪いアプローチですか?
C#.NETで記述したアプリケーション用に独自のファイル形式を作成して、保存情報を保存し、おそらくプロジェクトの資産を保存します。何らかの方法でこれを行う方法の基準はありますか?私は単純に行っていたSerialize
バイナリに私のオブジェクトとどのようにファイルを解析するために私に言うだろうヘッダを作成します。これは悪いアプローチですか?
回答:
最も簡単な方法は、おそらくXMLSerializer
クラスを使用して構造をXMLにシリアル化することです。おそらく、別個のヘッダーとボディ構造を作成する必要はないでしょうが、すべてのアセットをXMLにシリアル化します。これにより、独自のプログラムの外部でファイル構造を簡単に検査/編集することができ、簡単に管理できます。
ただし、ファイル構造が非常に複雑で、さまざまな種類のさまざまな種類のアセットが含まれているため、構造全体をXMLにシリアル化するのが面倒な場合はPackaging
、C#のライブラリを使用して、各アセットを個別にシリアル化し、単一のパッケージにコンパイルすることを検討してください。これは、基本的に.docx、.xslx、.pptx、およびその他のOfficeファイル形式の構築方法です。
protobuf-net
、データをシリアル化するために使用していますが、それは非常にうまく機能します。しかし、個別にピースをシリアル化する必要があるため、パッケージングライブラリで話していることは、私が必要としているように聞こえます。
多くのファイル形式を解析しなければならなかった誰かから、私はこれについて異なる視点からほとんどの意見を持っています。
マジックナンバーを非常にユニークなものにして、他のフォーマットの人々のファイルフォーマット検出器がそれをあなたのものと誤認しないようにしてください。バイナリを使用する場合は、マジックナンバーのバイナリフォーマットの開始時に、ランダムに生成された8または16バイトを割り当てます。XMLを使用する場合は、ドメインに適切な名前空間を割り当てて、他の人と衝突しないようにします。JSONを使用している場合、神はあなたを助けます。たぶん誰かが今までにフォーマットの忌まわしい解決策を見つけ出したのかもしれません。
後方互換性を計画します。ソフトウェアの新しいバージョンが違いに対処できるように、フォーマットのバージョン番号を何らかの方法で保存します。
ファイルが大きくなる可能性がある場合、または何らかの理由でスキップしたいセクションがある場合は、これを行うための良い方法があることを確認してください。XML、JSON、および他のほとんどのテキスト形式は、特に気に入らない場合でもリーダーが開始要素と終了要素の間のすべてのデータを解析することを強制するため、特にひどいです。EBMLは要素の長さを保存し、最後までスキップできるため、いくぶん優れています。カスタムバイナリ形式を作成する場合、ヘッダーに最初にチャンク識別子と長さを格納し、リーダーはチャンク全体をスキップできるという非常に一般的な設計があります。
すべての文字列をUTF-8で保存します。
長期的な拡張性が必要な場合は、すべての整数を可変長形式で保存してください。
チェックサムは、混乱する結果を生成する可能性のあるファイルのセクションにステップインするのではなく、無効なデータでリーダーが即座に中止できるため、便利です。
さて、あなたが説明することは非常に悪いアプローチになることがあります。これは、「シリアル化」と言うとき、オブジェクトを取得して何らかのバイナリストリームに直接出力する言語/フレームワークの機能を使用することについて話していることを前提としています。問題は、クラス構造が長年にわたって変化することです。すべてのクラスが新しいクラスで変更された場合、アプリの以前のバージョンで作成されたファイルを再ロードできますか?
ファイル形式の長期的な安定性を確保するために、スリーブを少しロールアップし、クラス内で独自の「シリアライズ」/「ストリーミング」メソッドを具体的に記述する方が良いことがわかりました。つまり、ストリームへの値の書き込みを手動で処理します。フォーマットバージョンを説明するヘッダーを記述し、必要なデータを必要な順序で保存します。読み取り側では、ファイルフォーマットの異なるバージョンの処理が非常に簡単になります。
もちろん、他のオプションはXMLまたはJSONです。バイナリの重いコンテンツには必ずしも最適ではありませんが、シンプルで人間が読める形式です...長期的な実行可能性には大きなプラスです。
また、私は考えを愛する自分より年以上の経験を持つ人々からこの質問への答えを聞くために。
私は仕事のためにいくつかのファイル形式を個人的に実装しましたが、XMLファイル形式の使用に移行しました。私がやり取りする要件とハードウェアは常に変化するため、今後この形式に追加する必要があるものはわかりません。XMLの主な利点の1つは、半構造化されていることです。このため、.NETが提供する自動XMLシリアル化は、正確な形式を期待するように強制するため、通常は避けます。
私の目標は、将来的に新しい要素と属性を追加し、可能な限りタグの順序を無視できるXML形式を作成することでした。ファイル全体をメモリにロードできることが確実な場合は、おそらくXPATHが適しています。
特に大きなファイルを処理している場合、または他の理由でファイルを一度にロードできない場合は、おそらくXmlStreamReaderを使用して既知の要素をスキャンし、ReadSubtreeでそれらの要素に再帰してスキャンします...
BinaryFormatter
ます。