質問

作成した大きなバイナリデータファイル(10〜100 GB)を読み取るシミュレーションがあります。速度上の理由からバイナリを使用しています。これらのファイルはシステムに依存しており、実行する各システムのテキストファイルから変換されるため、移植性については心配していません。現在、ファイルはfwriteで記述されたPOD構造体の多くのインスタンスです。

構造を変更する必要があるので、ファイルのバージョン番号を含むヘッダーを追加します。このヘッダーは、構造が変更されるたびに増加します。これをやっているので、他の情報も追加したいと思います。構造体のサイズ、バイト順、そしておそらくバイナリファイルを作成したコードのsvnバージョン番号を考えています。追加するのに役立つものは他にありますか?

役に立ちましたか?

解決

私の経験では、必要なデータを推測することは、常に無駄な時間です。重要なのは、拡張可能な方法でメタデータを構造化することです。 XMLファイルの場合、それは簡単ですが、バイナリファイルにはもう少し考える必要があります。

メタデータは、ファイルの先頭ではなく、末尾の構造に保存する傾向があります。これには2つの利点があります:

  • 切り捨てられた/切り捨てられていないファイルは 簡単に検出できます。
  • メタデータフッターはしばしば なしで既存のファイルに追加 読み取りコードに影響を与えます。

私が使用する最も単純なメタデータフッターは次のようになります。

struct MetadataFooter{
  char[40] creatorVersion;
  char[40] creatorApplication;
  .. or whatever
} 

struct FileFooter
{
  int64 metadataFooterSize;  // = sizeof(MetadataFooter)
  char[10] magicString;   // a unique identifier for the format: maybe "MYFILEFMT"
};

生データの後に、メタデータフッターとTHENファイルフッターが書き込まれます。

ファイルを読み取るときは、最後までシークします-sizeof(FileFooter)。フッターを読み、magicStringを確認してください。次に、metadataFooterSizeに従ってシークバックし、メタデータを読み取ります。ファイルに含まれるフッターのサイズに応じて、欠落しているフィールドにデフォルト値を使用できます。

KeithB が指摘しているように、この手法を使用してメタデータをXML文字列として保存することもでき、利点があります。バイナリデータのコンパクトさと速度を備えた、完全に拡張可能なメタデータの両方。

他のヒント

大規模なバイナリについては、HDF5(Googleの場合)を真剣に検討します。採用したいものではない場合でも、独自のフォーマットを設計する際に役立つ方向性を示すことがあります。

大きなバイナリの場合、バージョン番号に加えて、レコードカウントとCRCを配置する傾向があります。その理由は、大きなバイナリは、小さなバイナリよりも時間とともに、または転送中に切り捨てられたり破損したりする傾向があるためです。私は最近、Windowsがこれをうまく処理しないことを恐怖に感じました。エクスプローラを使用して、数百のファイルにわたって約2TBを接続されたNASデバイスにコピーし、各コピーの2〜3ファイルが破損していることがわかりました(完全ではないコピー)。

ファイルの種類の識別子は、後でバイナリファイルに他の構造を書き込む場合に役立ちます。 たぶん、これは短い文字列かもしれませんので、ファイルの内容を(16進エディタを介して)見ればわかります。

それらが大きければ、ファイルの先頭に健全なチャンク(64K?)のスペースを確保し、そこにXML形式でメタデータを置き、ファイルの終わりの文字(Ctrl-Z DOS / Windowsの場合、Unixの場合はctrl-D?)。そうすれば、XML用の幅広いツールセットを使用してメタデータを簡単に調べて解析できます。

それ以外の場合は、他の人がすでに言ったことに行きます。ファイル作成のタイムスタンプ、作成されたマシンの識別子、診断目的で基本的に考えられるその他のものです。そして理想的には、構造フォーマット自体の定義を含めることです。構造を頻繁に変更する場合、古いデータファイルのさまざまな形式を読み取るために適切なバージョンのコードを維持することは大きな苦痛です。

@highpercompが言及したHDF5の大きな利点の1つは、名前とデータ型が何らかの規則を持っている限り、構造形式の変更を心配する必要がないことです。構造体の名前とデータ型はすべてファイル自体に保存されるため、Cコードをスミレエンに吹き飛ばすことができます。それは問題ではなく、HDF5ファイルからデータを取得できます。これにより、データのフォーマットの心配が減り、データの構造の心配が増えます。つまり、HDF5の問題であるバイトシーケンスは気にしませんが、フィールド名などに注意してください。

HD興味深い。

@rstevensは、「ファイルの種類の識別子」と言いました...健全なアドバイス。従来、これはマジックナンバーと呼ばれ、ファイル内では不正使用の用語ではありません(コードでは不正使用の用語です)。基本的に、それはいくつかの数値であり、通常は少なくとも4バイトであり、通常、それらのバイトの少なくとも1つがASCIIでないことを確認します。 。 / etc / magic(またはローカルの同等物)にルールを記述して、マジックナンバーを含むファイルが特別なファイルタイプであることを報告することもできます。

ファイル形式のバージョン番号を含める必要があります。ただし、コードのSVN番号を使用しないことをお勧めします。ファイル形式が変更されていない場合、コードが変更される場合があります。

スキーマのバージョン管理に必要な情報に加えて、問題のトラブルシューティングを行う場合に役立つ可能性のある詳細を追加します。例:

  • ファイルが作成および更新されたときのタイムスタンプ(該当する場合)。
  • ビルドのバージョン文字列(理想的には、「公式」ビルドごとに自動インクリメントされるバージョン文字列があります。これはファイルスキーマバージョンとは異なります)。
  • ファイルを作成するシステムの名前、およびアプリに関連するその他の統計情報

これは、(a)顧客に提供するように依頼する必要がある情報を取得する際、および(b)正しい情報を取得する際に非常に有用であることがわかります-異なるバージョンのソフトウェアを実行していると報告する顧客の数は驚くべきものですデータが主張するものに!

ファイルオフセットをヘッダーの固定位置に配置することを検討してください。これにより、実際のデータがファイルのどこから始まるかがわかります。これにより、必要に応じてヘッダーのサイズを変更できます。

いくつかのケースでは、値0x12345678をヘッダーに挿入して、ファイル形式がそれを処理していたマシンのエンディアンと一致するかどうかを検出できるようにしました。

通信機器の構成とファームウェアのアップグレードの経験から、バージョン(ヘッダーの固定部分)から始まるいくつかの定義済みバイト(これは重要です)が本当に必要なだけであることがわかります。ヘッダーの残りの部分はオプションです。適切なバージョンを示すことにより、いつでも処理方法を表示できます。ここで重要なことは、ヘッダーの「可変」部分をファイルの最後に配置することです。ファイルの内容自体を変更せずにヘッダーの操作を計画する場合。また、これにより、変数ヘッダー部分を再計算する「追加」操作が簡素化されます。

固定サイズのヘッダーの機能が必要です(最初):

  • 共通の「長さ」フィールド(ヘッダーを含む)。
  • CRC32のようなもの(ヘッダーを含む)。

OK、可変部分XMLまたはヘッダー内のかなり拡張可能な形式は良い考えですが、本当に必要ですか? ASNエンコーディングの経験が豊富でした...ほとんどの場合、その使用法は行き過ぎました。

さて、 RFC 2126 (4.3章)。

ヘッダーにバージョン番号を入れている場合、POD構造体を変更するか、ヘッダーに新しいフィールドを追加する必要があるときはいつでもバージョンを変更できます。

それで、ヘッダーに何かを追加しないでください。興味深いかもしれません。維持する必要があるコードを作成しているだけですが、実際の価値はほとんどありません。

大きなファイルの場合、データ定義を追加して、ファイル形式が自己記述的になるようにすることができます。

私のバリエーションでは、ロディとジェイソンSのアプローチを組み合わせています。

要約-他の場所に保存されている長さを判断する方法で、フォーマットされたテキストメタデータをファイルの最後に配置します。

1)ファイルの先頭に長さフィールドを配置して、固定長を想定するのではなく、最後にメタデータの長さを把握します。そのようにして、メタデータを取得するには、その固定長の初期フィールドを読み取ってから、ファイルの終わりからメタデータBLOBを取得します。

2)メタデータにXML、YAML、またはJSONを使用します。これは、メタデータが最後に追加される場合に特に便利/安全です。ファイルを読み取る人は、XMLで始まるからといってすべてがXMLであると自動的に判断することはないからです。

このアプローチの唯一の欠点は、メタデータが大きくなる場合、ファイルの先頭と末尾の両方を更新する必要があることですが、とにかく他の部分が更新される可能性があります。最終アクセス日などのトリビアを更新するだけの場合、メタデータの長さは変更されないため、インプレース更新のみが必要です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top