さまざまな理由から、いくつかのかなり単純なオブジェクトをデータ ファイルにダンプするカスタム シリアライゼーションがあります。おそらく 5 ~ 10 個のクラスがあり、結果として得られるオブジェクト グラフは非循環的で非常に単純です (シリアル化された各オブジェクトには、シリアル化された別のオブジェクトへの 1 つまたは 2 つの参照があります)。例えば:
class Foo
{
final private long id;
public Foo(long id, /* other stuff */) { ... }
}
class Bar
{
final private long id;
final private Foo foo;
public Bar(long id, Foo foo, /* other stuff */) { ... }
}
class Baz
{
final private long id;
final private List<Bar> barList;
public Baz(long id, List<Bar> barList, /* other stuff */) { ... }
}
id フィールドはシリアル化のためだけにあるため、ファイルにシリアル化するときに、これまでにシリアル化された ID の記録を保持することでオブジェクトを書き込むことができます。次に、オブジェクトごとに、その子オブジェクトがシリアル化されているかどうかを確認して書き込みます。そうでないものは、データ フィールドとその子オブジェクトに対応する ID を書き込むことによって、最終的にオブジェクト自体を書き込みます。
私を困惑させているのは、IDを割り当てる方法です。考えてみると、ID の割り当てには次の 3 つのケースがあるようです。
- 動的に作成されたオブジェクト -- ID は増分するカウンターから割り当てられます
- ディスクからのオブジェクトの読み取り -- ディスク ファイルに格納されている番号から ID が割り当てられます
- シングルトン オブジェクト -- オブジェクトは、常に存在するシングルトン オブジェクトを表すために、動的に作成されるオブジェクトの前に作成されます。
これらを適切に処理するにはどうすればよいですか?私は車輪を再発明しているように感じ、すべてのケースを処理するための十分に確立された技術が必要です.
明確化:いくつかの接線情報と同様に、私が見ているファイル形式はおおよそ次のとおりです(関連するべきではないいくつかの詳細をざっと説明します)。かなり大量の高密度バイナリ データ (数十/数百 MB) を処理するように最適化されており、その中に構造化データを散在させることができます。密なバイナリ データは、ファイル サイズの 99.9% を占めます。
このファイルは、コンテナーとして機能する一連のエラー修正ブロックで構成されています。各ブロックは、一連のパケットで構成されるバイト配列を含むと考えることができます。パケットを一度に 1 つずつ連続して読み取ることができます (たとえば、各パケットの終わりがどこにあるかを知ることができ、その直後に次のパケットが開始されます)。
したがって、ファイルは、エラー修正レイヤーの上に格納された一連のパケットと考えることができます。これらのパケットの大部分は、この質問とは関係のない不透明なバイナリ データです。ただし、これらのパケットのごく一部は、シリアル化された構造化データを含むアイテムであり、オブジェクト参照関係によってリンクされる可能性のあるデータ「島」で構成される一種の「群島」を形成します。
したがって、パケット 2971 にシリアル化された Foo が含まれ、パケット 12083 にパケット 2971 の Foo を参照するシリアル化された Bar が含まれるファイルがあるとします (パケット 0 ~ 2970 および 2972 ~ 12082 は不透明なデータ パケットです)。
これらのパケットはすべて不変です (したがって、Java オブジェクト構築の制約があるため、非循環オブジェクト グラフを形成します)。そのため、可変性の問題に対処する必要はありません。これらは、共通Item
インターフェースの子孫でもあります。私がやりたいことは、任意のItem
オブジェクトをファイルに書き込むことです。Item
に既にファイルにある他の への参照が含まれている場合、Item
それらもファイルに書き込む必要がありますが、まだ書き込まれていない場合に限ります。そうしないと、それらを読み返すときに何らかの形で合体する必要がある重複が発生します。