德尔福:将多行字符串保存到文件



大家晚上好。

我有一个字符串列表,每条记录包含一个多行字符串。

我的字符串列表 [0]:

<li>
  Test1
</li>

我的字符串列表 [1]:

<a href="#">
  <b>      
    Test2
  </b>
</a>

等。

如何将这些字符串保存并加载到文件(文本、ini、二进制、记录、保存文件等(中?主要问题是我可以将其保存到文本文件中,但是在回读时,每行都被视为一条新记录,而第一条记录有 3 行,第二条记录有 5 行,依此类推。

您对保存和加载这些字符串的过程有什么建议?

如果将其保存到.txt文件,则无法正确重新加载它,因为您不知道 give 换行符最初是嵌入在字符串中,还是分隔了两个字符串。

如果将其保存为另一种文本格式,例如 .ini ,您可以根据需要转义/取消转义换行符,例如:

function Encode(const S: String): String;
begin
  Result := StringReplace(S, '<', '<<', [rfReplaceAll]);
  Result := StringReplace(Result, #13#10, '<CRLF>', [rfReplaceAll]);
  Result := StringReplace(Result, #13, '<CR>', [rfReplaceAll]);
  Result := StringReplace(Result, #10, '<LF>', [rfReplaceAll]);
end;
Ini := TIniFile.Create(...);
try
  Ini.WriteInteger('section', 'count', MyStringList.Count);
  for I := 0 to MyStringList.Count-1 do
    Ini.WriteString('section', IntToStr(I), Encode(MyStringList[I]);
finally
  Ini.Free;
end;

function Decode(const S: String): String;
begin
  Result := StringReplace(S, '<LF>', #10, [rfReplaceAll]);
  Result := StringReplace(Result, '<CR>', #13, [rfReplaceAll]);
  Result := StringReplace(Result, '<CRLF>', #13#10, [rfReplaceAll]);
  Result := StringReplace(Result, '<<', '<', [rfReplaceAll]);

结束;

Ini := TIniFile.Create(...);
try
  Count := Ini.ReadInteger('section', 'count', 0);
  for I := 0 to Count-1 do
    MyStringList.Add(Decode(Ini.ReadString('section', IntToStr(I), ''));
finally
  Ini.Free;
end;

如果将其保存为二进制格式,则可以按原样保留换行符,例如:

procedure WriteIntegerToStream(Stream: TStream; Value: Integer);
begin
  Stream.WriteBuffer(Value, SizeOf(Integer));
end;
procedure WriteStringToStream(Stream: TStream; const Value: String);
var
  U: UTF8String;
  Count: Integer;
begin
  U := UTF8String(Value); // or UTF8Encode(Value) prior to D2009
  Count := Length(U);
  WriteIntegerToStream(Stream, Count);
  if Count > 0 then
    Stream.WriteBuffer(PAnsiChar(U)^, Count * SizeOf(AnsiChar));
end;
Strm := TFileStream.Create(..., fmCreate);
try
  WriteIntegerToStream(Stream, MyStringList.Count);
  for I := 0 to MyStringList.Count-1 do
    WriteStringToStream(Stream, MyStringList[I]);
finally
  Stream.Free;
end;

function ReadIntegerFromStream(Stream: TStream): Integer;
begin
  Stream.ReadBuffer(Result, SizeOf(Integer));
end;
function ReadStringFromStream(Stream: TStream): String;
var
  Count: Integer;
  U: UTF8String;
begin
  Count := ReadIntegerFromStream(Stream);
  if Count > 0 then
  begin
    SetLength(U, Count);
    Stream.ReadBuffer(PAnsiChar(U)^, Count * SizeOf(AnsiChar));
    Result := String(U); // or UTF8Decode(U) prior to D2009
  end else
    Result := '';
end;
Stream := TFileStream.Create(..., fmOpenRead or fmShareDenyWrite);
try
  Count := ReadIntegerFromStream(Stream);
  for I := 0 to Count-1 do
    MyStringList.Add(ReadStringFromStream(Stream));
finally
  Stream.Free;
end;

最新更新