5

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;
9
  • 1
    What did you try? It looks like a Show me teh codez question right now. Commented Jan 27, 2012 at 11:00
  • Did you try the technique shown in my answer to your other question (stackoverflow.com/questions/8819885/…) or the variants suggest in the first comment to your other question? (stackoverflow.com/questions/3820996/…). You should try to solve this yourself and post the failing code. Without that, it really is a "Show me teh codez" question. Voting to close as "too localized" because this would only help YOU, no one else, ever. Commented Jan 27, 2012 at 11:05
  • @Cosmin Prund , No it's not Show me teh codez , But just to be honest i don't know how to Save and Load the Dynamic Array from Stream . Commented Jan 27, 2012 at 11:06
  • Do me a favor. Read the answers for the two questions I linked and try to solve this yourself. If you try and fail, post back a comment in no less then 60 minutes and I'll give you the code. Hint: the second question contains code to save a dynamic array. Commented Jan 27, 2012 at 11:08
  • stackoverflow.com/questions/3820996/… This's not my question , But i will try based on the suggestions . Thank you Commented Jan 27, 2012 at 11:08

2 Answers 2

6

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;
Sign up to request clarification or add additional context in comments.

Comments

5

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.

1 Comment

Updated documentation at synopse.info/files/html/… With a lot of new features, including JSON serialization.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.