请有人帮我保存并从流中加载动态数组
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;
答案 0 :(得分:5)
从Delphi 5到XE2的另一个解决方案是使用我们的核心OpenSource单元的一些功能。
事实上,它实现了:
您可以编码,例如
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进入数据库),但它不是它的一部分:只需要一个单元,也不需要SQLite3,也不需要整个ORM类。
答案 1 :(得分: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;