我正在尝试阅读和处理由Thunderebird创建的电子邮件文件。我正在使用TIdMessage
。它适用于绝大多数电子邮件,但有日期问题的电子邮件除外。
这是我的代码:
procedure TForm1.ButtonTestClick(Sender: TObject);
const
CRLF = #13#10;
var
IndyStringList: TStringList;
IndyStream: TMemoryStream;
IdMessage1: TIdMessage;
begin
IdMessage1 := TIdMessage.Create(nil);
s1 := 'C:\Temp\MboxTest4.txt'; // shortened problem file
IndyStringList := TStringList.Create;
IndyStream := TMemoryStream.Create;
IndyStringList.LoadFromFile(s1);
IndyStringList.Add(CRLF + '.' + CRLF);
IndyStringList.SaveToStream(IndyStream);
IndyStream.Position := 0;
try
IdMessage1.LoadFromStream(IndyStream);
except
on E: EConvertError do
ShowMessage(E.ClassName + ' ' + E.Message);
on E : Exception do
ShowMessage(E.ClassName+' error raised, with message : ' + E.Message);
end;
end;
当我使用包含错误Date
的文件运行此文件时,EConvertError
和Exception
处理程序不会执行,程序会继续执行,就好像没有错误一样。
这是电子邮件:
From - Mon Jan 1 00:00:00 1965 X-Persona: <support@LondonDatabases> Received: from yass.news.co.uk [194.129.35.178] by londondatabases.com (SMTPD32-6.06) id A3FA150060; Thu, 29 Aug 2002 10:47:22 -0400 From: Sunday Times Enterprise Network <01582485-001069-1644@yass.news.co.uk> To: support@londondatabases.com Date: Thu, 29 August 2002 15:40:46 +0100 (BST) Subject: The Sunday Times Enterprise Network Mime-Version: 1.0 Content-Type: text/html; charset=windows-1252 Content-Disposition: inline User-Agent: YASS Message-Id: <200208291047574.SM00940@yass.news.co.uk> X-RCPT-TO: <support@londondatabases.com> X-UIDL: 313625295 Status: U X-Mozilla-Status: 8000 X-Mozilla-Status2: 00000000 Content-transfer-encoding: 8bit <HTML> </html>
答案 0 :(得分:4)
您不应该使用TStringList
按照您的方式加载电子邮件文件(并且您不应该CRLF
使用TStringList.Add()
。没有理由手动将CRLF+'.'+CRLF
序列注入电子邮件数据(除非您使用的是非常旧版本的Indy,但尚未在内部处理)。您应该使用TIdMessage.LoadFromFile()
方法:
procedure TForm1.ButtonTestClick(Sender: TObject);
var
IdMessage1: TIdMessage;
begin
try
IdMessage1 := TIdMessage.Create(nil);
try
IdMessage1.LoadFromFile('C:\Temp\MboxTest4.txt');
finally
IdMessage1.Free;
end;
except
on E : Exception do
ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
end;
end;
或者,TIdMessageHelper.LoadFromFile()
方法,如果电子邮件的行没有以点透明格式转义(有关详细信息,请参阅New TIdMessage helper):
uses
..., IdMessageHelper;
procedure TForm1.ButtonTestClick(Sender: TObject);
var
IdMessage1: TIdMessage;
begin
try
IdMessage1 := TIdMessage.Create(nil);
try
// if using D2006+
IdMessage1.LoadFromFile('C:\Temp\MboxTest4.txt', False, False);
// if using pre-D2006
TIdMessageHelper_LoadFromFile(IdMessage1, 'C:\Temp\MboxTest4.txt', False, False);
finally
IdMessage1.Free;
end;
except
on E : Exception do
ShowMessage(E.ClassName + ' error raised, with message : ' + E.Message);
end;
end;
无论哪种方式,您的代码未捕获日期转换错误的原因是因为Indy在内部捕获了异常并将TIdMessage.Date
属性设置为0.0
。代码中没有引发异常,所以只有在IDE的调试器中运行代码时才能看到它。
电子邮件的Date
标头无法解析的原因是因为RFC 822 Section 5的规则格式不正确。 August
应该是Aug
,然后它会正确解析:
Date: Thu, 29 Aug 2002 15:40:46 +0100 (BST)
但是,Indy确实考虑了RFC 822不允许的几种替代语言拼写,但它没有处理完整的月份名称。所以我刚刚更新了Indy以支持解析其他拼写,现在你的原始“格式错误”Date
将无错误地解析。