从 RTF 文件中提取纯文本的函数给出了错误的结果
Function to extract plain text from RTF file gives wrong result
在 Windows 10 in Delphi 11 Alexandria 中的 32 位 VCL 应用程序中,我需要在 RTF 文件中搜索文本。所以我使用这个函数(发现here)从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
控件?
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;
TStringStream
构造函数不会像您期望的那样加载文件。 TStringStream
不是 TFileStream
。顾名思义,TStringStream
是 string
的流包装器。因此,它的构造函数接收一个字符串并将其 as-is 复制到流中。因此,您正在使用文件路径字符串本身的值加载 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;
也就是说,除了 TRichEdit
之外,在原生 RTL 或 VCL 中没有任何东西可以为您将 RTF 解析为 plain-text。如果您不想使用 TRichEdit
,您将不得不自己解析 RTF,或者寻找第三方解析器来使用。
在 Windows 10 in Delphi 11 Alexandria 中的 32 位 VCL 应用程序中,我需要在 RTF 文件中搜索文本。所以我使用这个函数(发现here)从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
控件?
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;
TStringStream
构造函数不会像您期望的那样加载文件。 TStringStream
不是 TFileStream
。顾名思义,TStringStream
是 string
的流包装器。因此,它的构造函数接收一个字符串并将其 as-is 复制到流中。因此,您正在使用文件路径字符串本身的值加载 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;
也就是说,除了 TRichEdit
之外,在原生 RTL 或 VCL 中没有任何东西可以为您将 RTF 解析为 plain-text。如果您不想使用 TRichEdit
,您将不得不自己解析 RTF,或者寻找第三方解析器来使用。