gpt4 book ai didi

arrays - Delphi 保存/加载动态数组失败

转载 作者:行者123 更新时间:2023-12-03 15:47:49 24 4
gpt4 key购买 nike

我认为这看起来像是“做作业”之类的问题,但我仍然处于“复制代码、使用它并尝试理解它”的状态' 阶段,这是我所知道的发布该主题问题最活跃的事情。

我有一条记录:

type
Card = record
Name: string;
Up,Right,Left,Down,Mark: Single;
IDNumber: Integer;
end;

以及该记录的数组:

var
ArrayCard: array of Card;

我想知道如何将这种动态数组存储到文件或从文件加载。

尝试使用这段代码:http://www.pascalgamedevelopment.com/showthread.php?6319-save-load-a-dynamic-array像这样:

Procedure TMainFrom.WriteMyData;

Var
FS : TFileStream;
I,iSize : Integer;
TmpPath: string;

Begin
TmpPath:= TPath.Combine(TPath.GetDocumentsPath, 'Cards.dat');
FS := TFileStream.Create(TmpPath, fmOpenWrite);
iSize:= Length(ArrayCard);
FS.WriteBuffer(iSize,SizeOf(iSize));
For I := 0 To iSize - 1 Do
FS.WriteBuffer(ArrayCard[I],SizeOf(Card));
FS.Free;
End;

到目前为止,它似乎有效,但后来我尝试像这样加载它:

Procedure TMainFrom.ReadMyData;

Var
FS : TFileStream;
I,iSize : Integer;
TmpPath: string;
TempCard : Card;

Begin
TmpPath:= TPath.Combine(TPath.GetDocumentsPath, 'Cards.dat');
FS := TFileStream.Create(TmpPath, fmOpenRead);
FS.ReadBuffer(iSize,SizeOf(iSize));
SetLength(ArrayCard,iSize);
For I := 0 To iSize - 1 Do
Begin
FS.ReadBuffer(TempCard,SizeOf(Card));
ArrayCard[I] := TempCard; //It Breaks Here...The Watch List: TempCard Inaccessible value
End;
FS.Free;
End;

我在模块中遇到异常 EAccessViolation...

然后我也尝试了这样的事情:delphi Save and Load dynamic array它用正确数量的项目加载数组,但它们都是空的或空白的:

procedure TMainFrom.SaveCardsToFile;
var
Stream: TStream;
L: Integer;
TmpPath: string;
ICount: Integer;
strm: TMemoryStream;

begin
TmpPath:= TPath.Combine(TPath.GetDocumentsPath, 'Cards.bin');

Stream:= TFileStream.Create(TmpPath, fmCreate);
L:= Length(ArrayCard);
Stream.WriteBuffer(L, SizeOf(L));
Stream.WriteBuffer(Pointer(ArrayCard)^, L * SizeOf(Card));
Stream.Free;
end;

procedure TMainFrom.LoadCardsFromFile;
var
Stream: TStream;
L: LongWord;
TmpPath: string;

begin
TmpPath:= TPath.Combine(TPath.GetDocumentsPath, 'Cards.bin');

Stream:= TFileStream.Create(TmpPath, fmOpenRead);
Stream.ReadBuffer(L, SizeOf(L));
SetLength(ArrayCard, L);
Stream.ReadBuffer(Pointer(ArrayCard)^, L * SizeOf(Card));
Stream.Free;
end;

最佳答案

不要对包含“正常”字符串的记录使用缓冲区操作。 string 只是指向字符串内容的指针,而不是 shortstring。因此,您的代码仅保存和加载指向字符串内容的指针,而不是字符串。如果加载的值指向无法访问的内存,您可能会遇到访问冲突。更改代码以单独保存和加载记录中的变量,如下所示:

type
TmyRec = record
str: string;
i: integer;
procedure SaveToStream(Stream: TStream);
procedure LoadFromStream(Stream: TStream);
end;

{ myRec }

procedure TmyRec.LoadFromStream(Stream: TStream);
var
strLen: integer;
strBuf: TBytes;
begin
Stream.Read(strLen, SizeOf(Integer));
SetLength(strBuf, strLen);
Stream.Read(strBuf, strLen);

str:=TEncoding.UTF8.GetString(strBuf);

Stream.Read(i, SizeOf(Integer));
end;

procedure TmyRec.SaveToStream(Stream: TStream);
var
strBuf: TBytes;
strLen: integer;
begin
// direct set encoding type helps to avoid problems with different platforms.
// for example, Windows uses UCS2, Android and iOS - UTF8 encoding
strBuf:=TEncoding.UTF8.GetBytes(str);
strLen:=Length(strBuf);

Stream.Write(strLen, SizeOf(Integer));
Stream.Write(strBuf, strLen);
Stream.Write(i, SizeOf(Integer));
end;

更新:你读过有关泛型的文章吗?您可以使用 TList 并在其中加载/保存记录,而不是动态数组:

type
TmyRecList = class(TList<TmyRec>)
public
procedure SaveToStream(Stream: TStream);
procedure LoadFromStream(Stream: TStream);
end;

{ TmyRecList }

procedure TmyRecList.LoadFromStream(Stream: TStream);
var
Len: integer;
i: Integer;
rec: TmyRec;
begin
Clear;

Stream.Read(Len, SizeOf(integer));

for i := 0 to Len-1 do
begin
Rec.LoadFromStream(Stream);
Add(rec);
end;
end;

procedure TmyRecList.SaveToStream(Stream: TStream);
var
i: Integer;
begin
Stream.Write(Count, SizeOf(Integer));
for i := 0 to Count-1 do
Items[i].SaveToStream(Stream);
end;

procedure THeaderFooterForm.FormCreate(Sender: TObject);
var
Stream: TStream;
rec: TmyRec;
recList: TmyRecList;
begin
Stream:=TMemoryStream.Create;
try
recList:=TmyRecList.Create;
try
rec.str:='sample text';
rec.i:=123;
recList.Add(rec);

rec.str:='another text';
rec.i:=234;
recList.Add(rec);

recList.SaveToStream(Stream);
Stream.Seek(0, soBeginning);

recList.LoadFromStream(Stream);
ShowMessage('this is str value in second record: ' + recList[1].str);
finally
recList.Free;
end;
finally
Stream.Free;
end;

关于arrays - Delphi 保存/加载动态数组失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35404596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com