将包含字符串类型的成员的记录保存到文件(Delphi,Windows) [英] saving a records containing a member of type string to a file (Delphi, Windows)
问题描述
我有一个类似于以下记录的记录:
I have a record that looks similar to:
type
TNote = record
Title : string;
Note : string;
Index : integer;
end;
简单。我选择将变量设置为字符串(而不是一个字符数组)的原因是我不知道这些字符串将要多长时间。它们可以是1个字符长,200或2000.
当然,当我尝试将记录保存到一个类型文件(...的文件)时,编译器抱怨说,我必须给一个字符串大小。
有没有办法克服这个?或者一种将这些记录保存到无类型文件的方法,并仍然保持一种可搜索的方式?
Simple. The reason I chose to set the variables as string (as opposed to an array of chars) is that I have no idea how long those strings are going to be. They can be 1 char long, 200 or 2000. Of course when I try to save the record to a type file (file of...) the compiler complains that I have to give a size to string. Is there a way to overcome this? or a way to save those records to an untyped file and still maintain a sort of searchable way?
请不要指出我可能的解决方案如果你知道解决方案,请发邮件。
谢谢
Please do not point me to possible solutions, if you know the solution please post code. Thank you
推荐答案
您不能使用类型化文件。尝试这样的一个TFileStream:
You can't do it with a typed file. Try something like this, with a TFileStream:
type
TStreamEx = class helper for TStream
public
procedure writeString(const data: string);
function readString: string;
procedure writeInt(data: integer);
function readInt: integer;
end;
function TStreamEx.readString: string;
var
len: integer;
iString: UTF8String;
begin
self.readBuffer(len, 4);
if len > 0 then
begin
setLength(iString, len);
self.ReadBuffer(iString[1], len);
result := string(iString);
end;
end;
procedure TStreamEx.writeString(const data: string);
var
len: cardinal;
oString: UTF8String;
begin
oString := UTF8String(data);
len := length(oString);
self.WriteBuffer(len, 4);
if len > 0 then
self.WriteBuffer(oString[1], len);
end;
function TStreamEx.readInt: integer;
begin
self.readBuffer(result, 4);
end;
procedure TStreamEx.writeInt(data: integer);
begin
self.WriteBuffer(data, 4);
end;
type
TNote = record
Title : string;
Note : string;
Index : integer;
procedure Save(stream: TStream);
end;
procedure TNote.Save(stream: TStream);
var
temp: TMemoryStream;
begin
temp := TMemoryStream.Create;
try
temp.writeString(Title);
temp.writeString(Note);
temp.writeInt(Index);
temp.seek(0, soFromBeginning);
stream.writeInt(temp.size);
stream.copyFrom(temp, temp.size);
finally
temp.Free;
end;
end;
我将离开Load过程给你。相同的基本思想,但它不应该需要一个临时流。在每个条目前面的记录大小,你可以阅读它,知道如果你正在寻找一个特定的记录,而不是阅读整个事情,可以跳过多远。
I'll leave the Load procedure to you. Same basic idea, but it shouldn't need a temp stream. With the record size in front of each entry, you can read it and know how far to skip if you're looking for a certain record # instead of reading the whole thing.
编辑:这是专门针对使用Unicode字符串的Delphi版本编写的。在旧版本上,您可以简化它。
This was written specifically for versions of Delphi that use Unicode strings. On older versions, you could simplify it quite a bit.
这篇关于将包含字符串类型的成员的记录保存到文件(Delphi,Windows)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!