ファイルの最初に、最後だけ知っているものを書き込む


9

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

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

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

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


1
/ sccsはこのように機能します。書き込みが完了すると、ファイルの先頭にすべてのバイトのチェックサムが書き込まれます。必要なファイル操作をアトミックに実行できるUnix(Solarisなど)でうまく機能し、それができないUnixで奇妙な散発的な問題を引き起こします(例:Linux
gnat

回答:


2

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

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

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

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


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


これは素晴らしい!それは私が気づいていなかったものであり、コアの問題を回避しますが、コアの問題を解決するための良い方法についてのガイダンスが欲しいのですが。古いソフトウェアは時期尚早に新しい要素で終了するため、未知のサイズの要素を使用すると、将来の互換性が制限される可能性があります。
pscheidler 2017

適切なDTDが必要であるか、EBMLを実際にデコードできない。まあ、すべての未知の要素のサイズが決まっている場合はスキップできますが、それで十分ですか?オフラインで保存したいEBMLがある場合は、後処理するだけです。
デュプリケータ

拡張する独自のスキーマを使用しています。古いソフトウェアは最終的に一部のデータをスキップする必要があるかもしれないという知識で設計されています。しかし、これは私が知らなかったEBMLの優れた機能なので、その答えを受け入れます。
pscheidler 2017

0

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

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

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

一般に、大きすぎる要素の数を最小限に抑えるようにしてください


まあ、彼はおそらく自分のEBML要素に対してそれを行うことができますが、それでも彼は親要素を手助けしません。
デュプリケータ

あなたのアイデアはうまくいきますが、スキーマを制約して大きな要素を回避するのではなく、大きな要素を処理できるシステムを作成したいと思います。
pscheidler 2017

このソリューションは大きな要素でも機能します。スタックサイズに注意してください。スキーマに関しては...アプリケーションが使用している言語と考えてください。複雑な言語を処理できない場合は、他の言語を調整するか、トランスレータが必要です。多くの開発者(少なくとも私が知っているC / C ++の開発者)は、火事のようにスキーマ/設計を変更する傾向があり、その結果、システムの質が低下します。他のコンポーネントが調整できない場合は、おそらく分解/設計が不十分です。変更しない他の理由がある場合は、おそらく別のハードウェアの使用を検討する必要があります
Whoot

0

KISSとYAGNI。
オプション#1を選択し、それが実際の問題になる場合は、それを繰り返します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.