简体   繁体   中英

delphi Save and Load dynamic array

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

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;

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, eg

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 (eg 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 .

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM