web-dev-qa-db-ja.com

ファイルの最初に、最後にしか知らないものを書き込む

背景: EBMLファイルを書き込むマイクロコントローラーCコードを書いています。 EBMLは要素がネストされたバイナリXMLに似ていますが、開始タグと終了タグの代わりに、開始ID、長さ、そしてデータがあります。低電力アプリケーションの外部フラッシュにこれを書き込んでいるので、フラッシュアクセスを最小限に抑えたいと思います。決して簡単なことはないので、メモリも制限されます。

EBML要素全体をメモリに保持できる場合、その長さがわかったら、各要素の長さに戻って入力できるため、生成は簡単です。問題は、要素全体をメモリに保持できない場合の対処方法です。私が見るオプションは:

  • 私が知っていることを書いてから、戻って長さを追加します(最も簡単ですが、必要以上にフラッシュアクセスを追加します)
  • 書き始める前に各要素の長さを計算します(比較的簡単ですが、プロセッサ時間は長くなります)
  • メモリがいっぱいになったらモードを切り替えて、データを続行しますが、すでにメモリに予約されている要素の長さを計算するだけです。次に、メモリにあるものを書き込み、戻って、中断したところからデータの処理を続けます。 (これまでのところ私のお気に入りのオプション)
  • 要素を書き込む必要があり、その最終的な長さがまだ不明な場合は、要素に最大または最悪の場合の長さを指定します。 (上記より簡単ですが、裏目に出てスペースを無駄にする可能性があります)

質問:これは、人々が考えていた比較的一般的な問題であるように思われます。一部のデータパケットを形成するときにも発生する可能性があることを知っています。私がここで見逃しているより良い/より一般的な/より受け入れられたテクニックはありますか?または、私が検索できる問題のいくつかの用語?

9
pscheidler

ペイロードの長さがわからない場合は、位置を覚えておらず、後で長さを埋め戻すことができなくても、心配することはほとんどありません。

「不明なサイズ」を書き留めてください。

その機能は、EBML要素と有効な子要素ではない次の要素で構成されるペイロードに依存します。

必要に応じて、後から作成したEBMLを好きな方法でオフラインで正規化できます。たとえば、「不明なサイズなし、最小サイズ」、「最小サイズ、不明なサイズを回避」などです。


詳細については、matroska.orgの EBML RFC Draft を参照してください。

2
Deduplicator

固定数のサブ要素を持つ単一の要素が大きすぎる場合は、スキーマで分割することをお勧めします。この形式はわかりませんが、おそらく最大長を定義できます。

シーケンスの場合、次のファイルに残っているサブエレメントと「ストリーム」の最大数を定義しようとすることができます

最大メモリサイズを超える可能性のある要素については、予約された要素の長さの場所と長さのカウンターのペアを含むスタックを準備します。ポップ時に現在のマーカーに現在のカウンターを保存し、その値を次のカウンターに追加します。

一般的に、大きすぎる要素の数を最小限に抑えるようにします

0
Whoot

KISSとYAGNI。
オプション#1を選択し、それが実際の問題になる場合-繰り返してください。

少なくとも類似のバイナリ形式を使用した類似のユースケースでは、このような方法でいくつかの値を入力するだけでよい場合は、これが最も簡単/最も簡単/最善のソリューションです。データのチャンクごとにこれを行う必要がある場合、アーキテクチャの欠陥になる可能性があります。

0
Kromster