0

在 Delphi 11 Alexandria 的 Windows 10 中的 32 位 VCL 应用程序中,我需要在 RTF 文件中搜索文本。所以我使用这个函数(在这里找到)从 RTF 文件中提取纯文本:

function RtfToText(const RTF_FilePath: string; ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
  MyStringStream: TStringStream;
begin
  RTFConverter := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    MyStringStream := TStringStream.Create(RTF_FilePath);
    try
      RTFConverter.Lines.LoadFromStream(MyStringStream);
      RTFConverter.PlainText := True;
      RTFConverter.Lines.StrictDelimiter := True;
      if ReplaceLineFeedWithSpace then
        RTFConverter.Lines.Delimiter := ' '
      else
        RTFConverter.Lines.Delimiter := #13;
      Result := RTFConverter.Lines.DelimitedText;
    finally
      MyStringStream.Free;
    end;
  finally
    RTFConverter.Free;
  end;
end;

但是,该函数返回的是 RTF 文件的文件路径,而不是 RTF 文件的纯文本内容!

这个函数有什么问题,我怎样才能有效地从 RTF 文件中提取纯文本而不必使用父TRichEdit控件?

4

2 回答 2

2

TStringStream构造函数不会像您期望的那样加载文件。TStringStream不是TFileStream。顾名思义,TStringStreamstring. 因此,它的构造函数接受一个字符串并将其原样复制到流中。因此,您正在使用文件路径字符串本身的值加载 RichEdit,而不是字符串所引用的文件的内容。

您实际上根本不需要TStringStream,因为TRichEdit可以直接加载文件,例如:

function RtfToText(const RTF_FilePath: string; ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
begin
  RTFConverter := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    RTFConverter.PlainText := False; 
    RTFConverter.Lines.LoadFromFile(RTF_FilePath);
    RTFConverter.PlainText := True;
    RTFConverter.Lines.StrictDelimiter := True;
    if ReplaceLineFeedWithSpace then
      RTFConverter.Lines.Delimiter := ' '
    else
      RTFConverter.Lines.Delimiter := #13;
    Result := RTFConverter.Lines.DelimitedText;
  finally
    RTFConverter.Free;
  end;
end;

话虽如此,在本机 RTL 或 VCL 之外没有任何东西TRichEdit可以为您将 RTF 解析为纯文本。如果您不想使用TRichEdit,则必须自己解析 RTF,或者找到要使用的第 3 方解析器。

于 2022-01-30T12:44:40.290 回答
0

Q 中的函数将 RTF 文件路径字符串直接分配给TStringStream而不加载 RTF 文件(正如@Remy Lebeau 正确观察到的那样:“TStringStream 构造函数不加载文件”)。

这是通过将 RTF 文件加载到TStringStream

function RtfToText(const RTF_FilePath: string; ReplaceLineFeedWithSpace: Boolean): string;
var
  RTFConverter: TRichEdit;
  MyStringStream: TStringStream;
begin
  RTFConverter := TRichEdit.CreateParented(HWND_MESSAGE);
  try
    MyStringStream := TStringStream.Create('');
    try
      MyStringStream.LoadFromFile(RTF_FilePath);
      RTFConverter.Lines.LoadFromStream(MyStringStream);
      RTFConverter.PlainText := True;
      RTFConverter.Lines.StrictDelimiter := True;
      if ReplaceLineFeedWithSpace then
        RTFConverter.Lines.Delimiter := ' '
      else
        RTFConverter.Lines.Delimiter := #13;
      Result := RTFConverter.Lines.DelimitedText;
    finally
      MyStringStream.Free;
    end;
  finally
    RTFConverter.Free;
  end;
end;
于 2022-01-30T12:18:35.353 回答