我有一个使用Indy库在delphi中编写的消息客户端,它接收电子邮件消息。我在解码MMS短信电子邮件时遇到了困难。
这些消息来自multipart/mixed
个电子邮件,其中一个消息部分(附件)为text/plain
(即base64编码),文件名为text0.txt
。
我的TIdMessageClient调用ProcessMessage(使用基于流的版本)来填充我将在屏幕上显示的TidMessage。但是当我浏览消息部分并试图解开它们时,那个附加文件就是我身边的一根刺。目前,我将附件的名称打印成一个正常工作的字符串(请参阅下面的代码片段,FBody是字符串类型),但无法获取文本文件的内容。
以下是有效的方法:
FBody := 'Attachment: ['+TidAttachment(Msg.MessageParts.Items[0]).FileName+']';
(编辑:)最初当我写这个问题时,我不确定附件是否存储在TidAttachmentFile或TidAttachmentMemory对象中。但是使用正确的调试器命令,我确定它是一个TidAttachmentFile。我想可以使用TidAttachmentFile.SaveToFile()将附件保存到磁盘上的文件,然后从磁盘读回文件,但这似乎浪费和缓慢(特别是对于200字符的文本消息)。如果可能的话,我真的更喜欢在没有临时文件的情况下“在内存中”执行此操作。
我需要做什么(a)使TidMessageClient返回TidAttachmentMemory对象而不是TidAttachmentObject(在ProcessMessage中),以及(b)将附加的文本文件读成字符串?
根据indy文档,我对这段代码看起来的起点大致如下:
TidAttachmentMemory(Msg.MessageParts.Items[0]).PrepareTempStream();
FBody := FBody + TidAttachmentMemory(Msg.MessageParts.Items[0]).DataString;
TidAttachmentMemory(Msg.MessageParts.Items[0]).FinishTempStream;
如果这不是正确的方式或使用TidAttachment(s),请随时指出我正确的方向。
答案 0 :(得分:3)
我想可以使用TidAttachmentFile.SaveToFile()将附件保存到磁盘上的文件中,然后从磁盘读回文件,但这看起来很浪费和慢(特别是对于200个字符的文本消息)。
使用TIdAttachmentFile
时,文件始终位于磁盘上。 TIdAttachmentFile.StoredPathName
属性指定实际文件的路径。 TIdAttachmentFile.SaveToFile()
方法仅将文件复制到指定位置。
我真的更喜欢这样做#34;在记忆中#34;如果可能的话,没有临时文件。
有可能。
我需要做什么(a)使TidMessageClient返回TidAttachmentMemory对象而不是TidAttachmentObject(在ProcessMessage中)
在TIdMessage.OnCreateAttachment
事件中,返回TIdAttachmentMemory
个对象,例如:
procedure TMyForm.IdMessage1CreateAttachment(const AMsg: TIdMessage; const AHeaders: TStrings; var AAttachment: TIdAttachment);
begin
AAttachment := TIdAttachmentMemory.Create(AMsg.MessageParts);
end;
如果没有为TIdMessage.OnCreateAttachment
事件分配处理程序,或者没有为AAttachment
分配任何内容,则默认情况下会创建TIdAttachmentFile
。
您可以选择实现自己的自定义TIdAttachment
派生类,如果您知道附件包含文本数据(TStringStream
参数会告诉您,请在内部使用AHeaders
)。
和(b)将附加的文本文件读成字符串?
根据indy文档,我对这段代码看起来的起点大致如下:
你很亲密。您需要使用TIdAttachment.OpenLoadStream()
方法而不是TIdAttachment.PrepareTempStream()
,并且需要读取TStream
返回TIdAttachment.OpenLoadStream()
的数据。在您的示例中,您可以使用Indy的ReadStringFromStream()
函数,例如:
// if using Indy 10.6 or later...
var
Attachment: TIdAttachment;
Strm: TStream;
begin
...
Attachment := TIdAttachment(Msg.MessageParts.Items[0]);
Strm := Attachment.OpenLoadStream;
try
FBody := FBody + ReadStringFromStream(Strm, -1, CharsetToEncoding(Attachment.Charset));
finally
Attachment.CloseLoadStream;
end;
...
end;
或者:
// if using Indy 10.5.x or earlier...
var
Attachment: TIdAttachment;
Strm: TStream;
Enc: TIdTextEncoding;
begin
...
Attachment := TIdAttachment(Msg.MessageParts.Items[0]);
Strm := Attachment.OpenLoadStream;
try
Enc := CharsetToEncoding(Attachment.Charset);
try
FBody := FBody + ReadStringFromStream(Strm, -1, Enc);
finally
Enc.Free;
end;
finally
Attachment.CloseLoadStream;
end;
...
end;