5


5

カスタムバイナリファイル形式でいくつかのデータを格納できるようにする必要があります。 私は今まで自分のファイルフォーマットを設計したことがありません。 これは、C#、Java、そしてRuby / Perl / Pythonの世界を行き来するための使いやすいフォーマットである必要があります。

ファイルから始めると、レコードで構成されます。 GUIDフィールドとJSON / YAML / XMLパケットフィールド。 何を区切り文字として使用するのかわかりません。 カンマ、タブ、または改行のようなものは壊れやすいようです。 Excelは何をするのですか? それともXML以前のOpenOfficeフォーマット? あなたはASCII文字0か1を使うべきです。 どこから始めたらいいかわからない。 このトピックに関する記事や本はありますか。

このファイルフォーマットは "ヘッダーセクション"を含むように後で拡張するかもしれません。

注:まず始めに.NETで作業しますが、フォーマットは移植しやすいものにしたいと思います。

  • UPDATE:* "パケット"の処理は遅くなることがありますが、ファイルフォーマット内のナビゲーションは遅くなります。 それで、私はXMLがテーブルの外にあると思います。

5 Answer


7


「プロトコルバッファ」を使ってみるのはどうですか。 効率的でポータブル、バージョン耐性のある汎用バイナリフォーマットとして設計された、それはあなたにhttp://code.google.com/p/protobuf/[googleライブラリ]でC、JavaとPython、そしてC#、Perl、Rubyを与えますその他http://code.google.com/p/protobuf/wiki/OtherLanguages [コミュニティポート]にありますか。

Guidは特定のデータ型を持っていませんが、(本質的に) `byte []`を持つメッセージとしてそれをシムすることができます。

通常 .NETの作業には、http://code.google.com/p/protobuf-net/[protobuf-net]をお勧めします(ただし、著者としては、やや偏見があります)。後で他の言語を使うつもりで、Jonのhttp://github.com/jskeet/dotnet-protobufs/tree/master[dotnet-protobufs]を使って(長期的に)もっとうまくやるかもしれません。それはあなたにプラットフォーム間でなじみのあるAPIを与えるでしょう(ここで、protobuf-netは.NETイディオムを使用します)。


2


ASCII文字0または1はそれぞれ数ビットを占有します(他の文字とまったく同じです)。したがって、格納している場合、「バイナリ」ファイルは本来の数倍になります。 0と1のテキストファイルは正確にはバイナリファイルではありません:)

http://msdn.microsoft.com/en-us/library/system.io.binarywriter.aspx[BinaryWriter]を使用して、生データを直接http://msdn.microsoft.com/en-usに書き込むことができます/library/system.io.filestream.aspx[file stream]。 あなたが理解する必要がある唯一の部分はあなたのインメモリフォーマット(通常ある種のオブジェクトグラフ)をBinaryWriterが消費できるバイトシーケンスに変換することです。

_しかし_あなたの主な関心が移植性であるならば、私は全くバイナリフォーマットに対してお勧めします。 [line-through] * XMLは移植性と相互運用性の問題を解決するために正確に設計されています。 ファイル形式としては冗長で重いですが、それは問題を解決するためのトレードオフです*人間が読める形式が表から外れている場合は、https://stackoverflow.com/questions/7949​​77/c -net-custom-binary-file-format-どこから始めるか/ 795014#795014 [Marc’s answer]は、やり方です。 ポータビリティホイールを作り直す必要はありません。


1


バイナリファイルに書き込むデータの種類とバイナリファイルの目的は異なります。 それらはクラスオブジェクトなのか、それとも単にデータを記録するのか。 それが記録データであるならば、私はそれをxmlフォーマットに入れることを勧めます。 そうすれば、ファイルがあなたの標準に準拠していることを検証するためのスキーマ検証を含めることができます。 Javaと.NETの両方に、XML形式との間でデータをインポートおよびエクスポートするためのツールがあります。


1


フォーマットが次のようになっているとします。

    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
    }

それから私はシーケンシャルファイルを持っているでしょう:

'' '' '

byte // a

バイト// b

int //名前のサイズ

char [] // name(上記で指定したサイズを持ちます。.NETではcharは16ビットであることを忘れないでください)

int // MyTypeEnum型

int //データサイズ

byte [] // data(上記で指定されたサイズを持ちます)

'' '' '

その後、最後の3行を必要なだけ繰り返すことができます。

読むためには、バイト、整数そして一連のバイトの読み込みをサポートする `BinaryReader`を使います。 `BinaryWriter`もあります。

さらに、Microsoft .NET(つまりWindows / Intelマシン上)はリトルエンディアンであることを忘れないでください。 それは BinaryReader`と BinaryWriter`でもあります。


1


移植可能なバイナリファイル形式を作成するための一般的なヒントをいくつか追加します。

バイナリファイル形式を発明することは、その中のビットがどのように行かなければならないか、そしてそれらが何を意味するのかを文書化することを意味することに注意してください。 コーディングではなくドキュメントです。

今ヒント:

  1. *エンディアン*をどうするかを決めます。 簡単で効果的な方法は、一度だけ永遠に決定することです。 一般的なPC(x86)で変換(パフォーマンス)を節約するために選択される場合は、この選択をリトルエンディアンにすることをお勧めします。

  2. * header *を作成してください。 はい、常にヘッダを持つことは良い考えです。 ファイルの最初のバイトがあなたに教えてくれるはずです。

    • あなたのフォーマットを認識することができるように魔法で始めてください(ASCII文字列はトリックをするでしょう)

    • バージョンを追加 あなたのファイルフォーマットのバージョンは追加しても大丈夫ですし、それはあなたが後に後方互換性をすることを可能にするでしょう。

  3. 最後にデータを追加します。 今、データの形式は特定され、それは常にあなたの正確なニーズに基づいています。 基本的に、データは何らかのデータ構造のバイナリイメージに格納されます。 データ構造はあなたが思いつく必要があるものです。

あなたがデータにランダムにアクセスする必要がある場合は、https://en.wikipedia.org/wiki/B-tree[B-Trees]を選択してください。それらすべてを読み、それからそれらすべてを読んでください。「配列」がうまくいくでしょう。

さらに、前方互換性のために TLV(Type-Length-Value)の概念を使用することもできます。