从RTF文件中提取纯文本的函数给出了错误的结果



在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文件的文件路径!

此函数有什么问题,如何在不使用父级TRichEdit控件的情况下有效地从RTF文件中提取纯文本?

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,或者找到第三方解析器来使用。

Q中的函数在不加载RTF文件的情况下直接将RTF文件路径字符串分配给TStringStream(正如@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;

最新更新