レコードリストをストリームに保存する

ども、Norimakiです。

アプリケーションでは、通常、データを作ったりしますが、
そのデータはアプリケーション内ではレコードの構造体で保持する
という場合が僕の場合は多いです。

例えば、所有しているブログとかメールアドレスとかのデータなどですね。

そういう場合は大体、データは1つではなく
複数のデータからなるということになるのですが、
その場合は、TListを使用してデータ群を溜めておきます。

最近のDelphiにはジェネリクスという便利な機能が備わったみたいで、

TList<String>

とか

TList<TNYUserDataRec>

のように(TNYUserDataRecは独自のレコード構造体です)
リスト化して保持することができます。

場合によっては、TDictionaryを使ったりします。

で、あとはファイルなどにデータを保存したり、
ファイルからデータを読み出したりできれば、
アプリケーションのデータI/O処理機能としては、
まぁ満足されるかなと。

ということで、

レコードリストをストリームに保存して、
そのストリームからファイルに保存すれば良いだろうと。
とまぁ、考えられます。

大体の流れとしては、まず、2つのストリームを使います。
データ全体を保存するためのストリーム(1)と、
1つのデータ(レコード)を扱うためのストリーム(2)です。

手順としては、1つのレコードをフィールドごとにストリーム(2)に保存します。
で、保存したストリーム(2)をストリーム(1)に保存(追記)します。

それをレコードの数だけ繰り返すという単純なもの。

ただ、いくつレコードがあるのかという情報も保存しておかなければいけないので、
その情報を、レコードデータを保存するよりも前に保存しておきます。

この際、レコードデータのカウントもレコードデータと同様に、
ストリーム(2)で保存しておきます。

カウンタだけなら、

Stream.Write(Count,SizeOf(Count));

というような記述でOKなんですが、そうではなくて、
一旦、このレコードカウンタもストリーム(2)に保存して、
その後、全体のストリーム(1)に保存するという方法を採用します。

実際、ファイルに保存したい内容ってのは、
レコードのカウンタだけではないですし、
後々、増える可能性もあるわけです。

となると、
レコードデータ以外のデータも1つのブロックとして、
可変サイズに対応しておくべきかなと。そう思うわけです。

レコードデータ以外の保存すべきデータが増減しても、
とりあえず、ブロック部分(ヘッダーブロック)を読んでおけば、
その後のレコードデータの読み込みには影響を与えませんので。

大体がファイルバージョンで管理するんでしょうけど、
処理対象部分を、ストリーム全体(1)とするか、
ストリームのブロック部分(2)にするかで、
対処の面倒くささってのが変わってくるのかなと。

そう思ったので、分けてみた次第です。

で、ストリームの読み書きに関する参考文献がこちら。
>>ストリームにデータを読み書きする

クラスヘルパーとoverloadを使って、ストリームに対する処理を
ちょっとだけ楽にしてくれています。

ということで、こんな感じで使えればと。

こんな感じで。

サンプルレコード(TNYFirstItemRec)には、
initとClearStringというプロシージャがありますが、
これはレコード初期化のためのプロシージャです。

initとClearStringに分けているのは気分です。

TVirtualTreeViewでノードを解放するときにレコードのフィールドに文字列がある場合,
文字列は空文字にしてから開放しないとメモリリークを起こすんですが、その感覚です。

そんな感じでしょうか。

ではでは。
Norimakiでした。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする