Delphi:将多行字符串保存到文件

Delphi:将多行字符串保存到文件,delphi,tstringlist,Delphi,Tstringlist,大家晚上好 我有一个字符串列表,每条记录都包含一个多行字符串 MyStringList[0]: <li> Test1 </li> 测试1 MyStringList[1]: <a href="#"> <b> Test2 </b> </a> 等等 如何将这些字符串保存并加载到文件(文本、ini、二进制、记录、savetofile等)?主要问题是,我无法将其保存到文本文件中,但在回读时

大家晚上好

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

MyStringList[0]:

<li>
  Test1
</li>
  • 测试1
  • MyStringList[1]:

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

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


    对于保存和加载这些字符串的进程,您有什么建议

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

    如果将其保存为另一种文本格式,如
    .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;
    
    如果将其保存为二进制格式,则可以按原样保留换行符,例如:

    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;
    


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

    如果将其保存为另一种文本格式,如
    .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;
    
    如果将其保存为二进制格式,则可以按原样保留换行符,例如:

    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;
    


    如果将其保存为文本文件,则无法恢复信息。您的
    MyStringList[0]
    是一个单行字符串<代码>
  • 不会导致断线<代码>
  • Test1
  • 在一行中是完全有效的HTML。如果在文件中使用换行符写入,它将作为单独的行读回。如果您存储了
  • 换行符`Test1
    换行符
    `,那么它不是一个单行字符串。@Ken我认为字符串列表中的字符串包含换行符,它确实包含换行符:“
  • #10#13 Test1#10#13
  • ”您是否准备保存一个单独的文件,其中说明换行符的位置?如果将其保存为文本文件,则无法恢复信息。您的
    MyStringList[0]
    是一个单行字符串<代码>
  • 不会导致断线<代码>
  • Test1
  • 在一行中是完全有效的HTML。如果在文件中使用换行符写入,它将作为单独的行读回。如果您存储了
  • 换行符`Test1
    换行符
    `,那么它不是一个单行字符串。@Ken我认为字符串列表中的字符串包含换行符,它确实包含换行符:“
  • #10#13 Test1#10#13
  • ”您是否准备保存一个单独的文件,其中说明了换行符的放置位置?您的二进制示例似乎很好。我要试一试。非常感谢您需要避开
    的任何实例。二进制文件要干净得多。@DavidHeffernan:或者至少escape
    您的二进制文件样本看起来不错。我要试一试。非常感谢您需要避开
    的任何实例。二进制文件要干净得多。@DavidHeffernan:或者至少是escape
    
    
    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;