簡體   English   中英

如何在Delphi中將動態數組保存到FileStream?

[英]How Can I Save a Dynamic Array to a FileStream in Delphi?

我在Delphi 2009中有以下結構:

type
  IndiReportIndi = record
    IndiName: string;
    NameNum: integer;
    ReportIndiName: string;
  end;

var
  XRefList: array of IndiReportIndi;

其中XRefList是動態數組。

我想將XRefList保存到FileStream。 我該怎么做並包括所有IndiName和ReportIndiName字符串,以便以后從FileStream加載時它們都可以再次檢索?

type
  IndiReportIndi = record
    IndiName: string;
    NameNum: integer;
    ReportIndiName: string;
    procedure SaveToStream(Stream: TStream);
    procedure LoadFromStream(Stream: TStream);
  end;

type
  TXRefList = array of IndiReportIndi;

function LoadString(Stream: TStream): string;
var
  N: Integer;

begin
  Result:= '';
  Stream.ReadBuffer(N, SizeOf(Integer));
  if N > 0 then begin
    SetLength(Result, N);
//    Stream.ReadBuffer(Result[1], N * SizeOf(Char));
// fast version - see comment by A.Bouchez
    Stream.ReadBuffer(Pointer(Result)^, N * SizeOf(Char));
  end;
end;

procedure SaveString(Stream: TStream; const S: string);
var
  N: Integer;

begin
  N:= Length(S);
  Stream.WriteBuffer(N, SizeOf(Integer));
  if N > 0 then
//    Stream.WriteBuffer(S[1], N * SizeOf(Char));
// fast version - see comment by A.Bouchez
    Stream.WriteBuffer(Pointer(S)^, N * SizeOf(Char));
end;

procedure IndiReportIndi.LoadFromStream(Stream: TStream);
var
  S: string;

begin
  IndiName:= LoadString(Stream);
  Stream.ReadBuffer(NameNum, SizeOf(Integer));
  ReportIndiName:= LoadString(Stream);
end;

procedure IndiReportIndi.SaveToStream(Stream: TStream);
begin
  SaveString(Stream, IndiName);
  Stream.WriteBuffer(NameNum, SizeOf(Integer));
  SaveString(Stream, ReportIndiName);
end;

function LoadXRefList(Stream: TStream): TXRefList;
var
  N: Integer;
  I: Integer;

begin
  Stream.ReadBuffer(N, SizeOf(Integer));
  if N <= 0 then Result:= nil
  else begin
    SetLength(Result, N);
    for I:= 0 to N - 1 do
      Result[I].LoadFromStream(Stream);
  end;
end;

procedure SaveXRefList(Stream: TStream; const List: TXRefList);
var
  N: Integer;
  I: Integer;

begin
  N:= Length(List);
  Stream.WriteBuffer(N, SizeOf(Integer));
  for I:= 0 to N - 1 do
    List[I].SaveToStream(Stream);
end;

使用: http//code.google.com/p/kblib/

type
  IndiReportIndi = record
    IndiName: string;
    NameNum: integer;
    ReportIndiName: string;
  end;

  TXRefList = array of IndiReportIndi;

var
  XRefList: TXRefList;

要將整個XRefList保存為流使用:

TKBDynamic.WriteTo(lStream, XRefList, TypeInfo(TXRefList));

要加載它:

TKBDynamic.ReadFrom(lStream, XRefList, TypeInfo(TXRefList));
var
  S: TStream;
  W: TWriter;
  A: array of IndiReportIndi;
  E: IndiReportIndi;
  ...
begin
  S := nil;
  W := nil;
  try 
    S := TFileStream.Create(...);
    W := TWriter.Create(S);
    W.WriteInteger(Length(A));
    for E in A do
    begin
      W.WriteString(E.IndiName);
      W.WriteInteger(E.NameNum);
      W.WriteString(E.ReportIndiName);
    end;
  finally
    W.Free;
    S.Free
  end;
end;  

要讀取這些數據,請使用TReader和ReadInteger / ReadString。

簡單的TFileStreamEx來保存變量

http://forum.chertenok.ru/viewtopic.php?t=4642

從2005年起與他們合作,沒有任何問題......

測試解決方案:

procedure TForm1.FormCreate(Sender: TObject);
VAR Stream: TFileStream;
    R: IndyRecordIndy;
begin
 Stream:= TFileStream.Create;
 TRY
   //put rec in stream
   Stream.WriteBuffer(R, SizeOf(R));

   //restore record from stram
   Stream.Position := 0;
   Stream.ReadBuffer(R, Stream.Size);
 FINALLY
  FreeAndNil(Stream);
 END;
end



;

只是為了准確答案:

考慮一下TDynArray包裝器,它能夠將任何記錄序列化為二進制文件,也可以將動態數組序列化。

有許多TList的方法,包括新方法(如散列或二進制搜索)。

針對速度和磁盤使用進行了優化,適用於Delphi 5到XE2 - 以及開源。

另請參見如何在TList中存儲動態數組?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM