2012-01-27 9 views
3

をロード誰かがストリームからと動的配列

const 
     iGlobHolderCount = 100; 

    type 
     TFiLeSpec = record 
     iSize: Integer; 
     end; 

     TFileSpecLst = array of TFiLeSpec; 

     TFiLeSpecList = record 
     iMin: Integer; 
     iMax: Integer; 
     iCount: Integer; 
     FileSpecLst: TFileSpecLst; 
     end; 


var 
FFileSpec: array of TFiLeSpec; 

FFileSpecList: array [1 .. iGlobHolderCount] of TFiLeSpecList; 
+1

あなたは何を試しましたか?これは、今、私のコードを表示するように見えます。 –

+0

あなたの他の質問(http://stackoverflow.com/questions/8819885/delphi-save-and-load-binary-tree)への私の答えに示されているテクニックを試しましたか?質問? (http://stackoverflow.com/questions/3820996/delphi-2010-how-to-save-a-whole-record-to-a-file)。これを自分で解決し、失敗したコードを投稿するようにしてください。それがなければ、本当に「私のコードを表示する」という質問です。これはあなた、他の誰も、あなたを助けるに過ぎないので、 "あまりにもローカライズされた"と閉じる投票。 –

+0

@Cosmin Prund、No it's not teh codez、正直言って ストリームからダイナミックアレイを保存してロードする方法がわかりません。 – Alexis

答えて

4

をその動的配列を保存と読み込みに私を助けることができますしてください最初の配列の長さを書き込み、および配列データ次:

type 
    TItem = Integer; 
    TItemArray = array of TItem; 

var 
    Stream: TStream; 
    Arr: TItemArray; 
    L: LongWord; 

begin 
    Arr:= TItemArray.Create(1, 2, 3); 
// To save 
    Stream:= TFileStream.Create('C:\Temp\test.bin', fmCreate); 
    L:= Length(Arr); 
    Stream.WriteBuffer(L, SizeOf(L)); 
    Stream.WriteBuffer(Pointer(Arr)^, L * SizeOf(TItem)); 
    Stream.Free; 
// To load 
    Stream:= TFileStream.Create('C:\Temp\test.bin', fmOpenRead); 
    Stream.ReadBuffer(L, SizeOf(L)); 
    SetLength(Arr, L); 
    Stream.ReadBuffer(Pointer(Arr)^, L * SizeOf(TItem)); 
    Stream.Free; 
end; 
5

Delphi 5からXE2までの別のソリューションは、当社のコアOpenSourceユニットのいくつかの機能を使用することです。実際に

、それが実装さ:

  • レコードタイプを処理するためのいくつかの低レベルのRTTI機能:RecordEquals、RecordSave、RecordSaveLength、RecordLoadと、
  • ダイナミック配列の周りのラッパーで、レコード、文字列、またはその他のダイナミック配列を含む動的配列の周りにTListのようなメソッドを公開できる、専用のTDynArrayオブジェクト。動的配列をシリアライズすることができます。
  • シリアル化では、最適化されたバイナリ形式が使用され、レコードまたはダイナミック配列をRawByteStringとして保存およびロードできます。

var 
    FFileSpec: array of TFiLeSpec; 
    TFileSpecList = array of TFiLeSpecList; 
    FFileSpecList: TFileSpecList; 

var FSL: TDynArray; 
    Bin: RawByteString; 
begin 
    FSL.Init(TypeInfo(TFiLeSpecList),FFileSpecList); 
    // ... then you use FFileSpecList[] as usual 
    // ... or use some methods of FSL: 
    if FSL.Count>0 then 
    FSL.Delete(0); 
    FSL.Add(FFileSpec); 
    FSL.Clear; 
    // then you can serialize the content to binary 
    Bin := FSL.SaveTo; 
    // use FSL.LoadFrom(Bin) to read the whole array content back 
    // or you can use a TStream 
    FSL.SaveToStream(aStream); 
    FSL.Clear; 
    aStream.Position := 0; 
    FSL.LoadFrom(aStream); 
    // you do not need to release nor Free FSL: this is a wrapper around FFileSpecList 
end; 

私は動的配列してTFileSpecListを交換しましたが、あなたは追加のRTTI提供するために、レコードの内部で、代わりに固定された配列を使用することができます注 - その後、RecordLoad/RecordSave関数を使用します。これはRTTI(Delphi 5でも)を使用して内部の動的配列内容を保存し、stringまたは入れ子配列を内部で処理します。

これは私たちのmORMotフレームワークで使用されています(たとえば、動的配列のserializationはDBに入ります)。しかし、それは一部ではありません:1ユニット、SQLite3もORMクラスも必要です。

this page for additional informationを参照してください。

+0

http://synopse.info/files/html/Synopse%20mORMot%20Framework%20SAD%201.18.html#TITL_48 JSONのシリアル化を含む多くの新機能が追加されました。 –