delphi Save and Load dynamic array

前端 未结 2 697
礼貌的吻别
礼貌的吻别 2021-01-19 02:51

please can someone help me in saving and loading its Dynamic array from a Stream

const
      iGlobHolderCount = 100;

    type
      TFiLeSpec = record
             


        
相关标签:
2条回答
  • 2021-01-19 03:20

    Another solution, working from Delphi 5 up to XE2, is to use some features of one our core OpenSource unit.

    In fact, it implements:

    • some low-level RTTI functions for handling record types: RecordEquals, RecordSave, RecordSaveLength, RecordLoad;
    • a dedicated TDynArray object, which is a wrapper around any dynamic array, able to expose TList-like methods around any dynamic array, even containing records, strings, or other dynamic arrays. It's able to serialize any dynamic array.
    • Serialization uses an optimized binary format, and is able to save and load any record or dynamic array as RawByteString.

    You can code, e.g.

    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;
    

    Note that I've replace your TFileSpecList by a dynamic array, but you may use a fixed array instead, inside a record to provide additional RTTI - then use RecordLoad / RecordSave functions. It will save the internal dynamic array content using RTTI (even with Delphi 5), handling any string or nested array within.

    It's used by our mORMot framework (e.g. for serialization of dynamic arrays into the DB), but it's not part of it: just one unit, nor SQLite3 nor the whole ORM classes are needed.

    See this page for additional information.

    0 讨论(0)
  • 2021-01-19 03:35

    Write first the length of an array, and next the array data:

    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;
    
    0 讨论(0)
提交回复
热议问题