在 Delphi 中如何将动态数组保存到 FileStream?

发布于 2024-10-06 12:32:18 字数 346 浏览 7 评论 0原文

我在 Delphi 2009 中有以下结构:

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

var
  XRefList: array of IndiReportIndi;

其中 XRefList 是动态数组。

我想将 XRefList 保存到 FileStream。我该如何做到这一点并包含所有 IndiName 和 ReportIndiName 字符串,以便稍后从该 FileStream 加载时可以再次检索它们?

I have the following structures in Delphi 2009:

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

var
  XRefList: array of IndiReportIndi;

where XRefList is a dynamic array.

I want to save XRefList to a FileStream. How do I do that AND include all the IndiName and ReportIndiName strings so that they will all be retrievable again when I later load from that FileStream?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

若无相欠,怎会相见 2024-10-13 12:32:18
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;
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;
属性 2024-10-13 12:32:18

使用: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));

Use: http://code.google.com/p/kblib/

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

  TXRefList = array of IndiReportIndi;

var
  XRefList: TXRefList;

To save whole XRefList to stream use:

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

To load it back:

TKBDynamic.ReadFrom(lStream, XRefList, TypeInfo(TXRefList));
自由范儿 2024-10-13 12:32:18
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。

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;  

To read those data you use a TReader and ReadInteger/ReadString.

葬﹪忆之殇 2024-10-13 12:32:18

简单的 TFileStreamEx 保存变量

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

从2005年开始就和他们一起工作,没有任何问题......

Simple TFileStreamEx to save variables

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

Work with them from 2005th year, without any problems...

美胚控场 2024-10-13 12:32:18

只是为了准确的答案:

考虑看看 TDynArray 包装器,它能够将任何记录序列化为二进制,也可以与动态数组进行序列化。

有很多类似 TList 的方法,包括新方法(例如散列或二分搜索)。

针对速度和磁盘使用进行了非常优化,适用于 Delphi 5 至 XE2 - 和开源。

另请参阅如何在 TList 中存储动态数组?

Just for the answer to be accurate:

Consider taking a look at the TDynArray wrapper, which is able to serialize any record into binary, and also to/from dynamic arrays.

There are a lot of TList-like methods, including new methods (like hashing or binary search).

Very optimized for speed and disk use, works for Delphi 5 up to XE2 - and Open Source.

See also How to store dynamic arrays in a TList?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文