Indy SaveToFile vs SaveToStream和BCC

时间:2013-10-28 01:01:03

标签: delphi stream c++builder indy

我理解Indy开发人员选择在使用SaveToStream时删除邮件的BCC标头,因为stream可以基于套接字。但是,如果我想将消息实际保存到流中以进行进一步处理,该怎么办?如果我想在结束后删除CRLF.CRLF,该怎么办?这样的例子是将消息保存到MBOX类型的文件。这当然不能直接完成。

所以我现在的方法真是一团糟:

// Writing to MBOX
// Save to temp file
IdMsg->SaveToFile("filenamewrite.tmp",false);

// Make file shorter by 5 trailing bytes
boost::scoped_ptr<TFileStream> fs(new TFileStream("filenamewrite.tmp", fmOpenWrite | fmShareDenyWrite));
fs->Size = fs->Size-5;
FlushFileBuffers(reinterpret_cast<void *>(fs->Handle));

// Now this file can be copied to another stream with "mbox"-like file.

加载:

// Reading from MBOX
boost::scoped_ptr<TFileStream> fs(new TFileStream("mboxfile", fmOpenRead | fmShareDenyWrite));
AnsiString Data;
Data.SetLength(12345);
fs->Read(const_cast<void *>(Data.data()), Data.Length());
boost::scoped_ptr<TStringList> sl(new TStringList);
sl->Text = Data;
sl->SaveToFile("filenameread.tmp");
IdMsg->LoadFromFile("filenameread.tmp");

当然,这是非常无效的方式,并且完全没必要。如果可以直接保存到流,那么将是2行代码而不是上面的混乱。

有更好的方法吗?如何添加重载SaveToStream以允许删除CRLF.CRLF并在Indy中保存BCC标头?从MBOX加载消息时LoadFromStream类似,因此可以直接从流加载,而无需添加尾随的CRLF.CRLF。

1 个答案:

答案 0 :(得分:2)

TIdMessage仅在调用BCC时写入TIdMessage.SaveToFile()标头。在不更改Indy的源代码或使用hack类的情况下,无法使TIdMessage.SaveToStream()写入BCC标头。但是,您可以在BCC属性中手动存储TIdMessage.ExtraHeaders数据,以便SaveToStream()可以将其写入。

至于处理额外的点等,这是因为加载/写入实际上是由TIdMessageClient完成的,TIdIOHandlerStreamMsg没有流的概念,或者除POP3 / SMTP之外的任何源/目的地的任何概念。这是Indy当前架构中的一个硬编码限制,将在Indy 11中解决。同时,有使用IdMsg->ExtraHeaders->Values["Bcc"] = EncodeAddress(IdMsg->BCCList, 'B', "utf-8"); boost::scoped_ptr<TIdMessageClient> msgClient(new TIdMessageClient(NULL)); boost::scoped_ptr<TIdIOHandlerStreamMsg> io(new TIdIOHandlerStreamMsg(NULL, NULL, Target Stream Goes Here); io->UnescapeLines = true; // <-- this is the key step! io->FreeStreams = false; msgClient->IOHandler = io.get(); msgClient->SendMsg(IdMsg, false); 类的解决方法。

试试这个:

IdMsg->Clear();
boost::scoped_ptr<TIdMessageClient> msgClient(new TIdMessageClient(NULL));
boost::scoped_ptr<TIdIOHandlerStreamMsg> io(new TIdIOHandlerStreamMsg(NULL, Source Stream Goes Here, NULL);
io->EscapeLines = true; // <-- this is the key step!
io->FreeStreams = false;
msgClient->IOHandler = io.get();
io->Open();
msgClient->ProcessMessage(IdMsg, false);

UnescapeLines=true

TIdIOHandlerStreamMsg会导致TIdMessageClient以静默方式撤消TIdMessage在保存EscapeLines=true时写入的额外数据。

TIdIOHandlerStreamMsg会导致TIdMessageClient添加TIdMessage在加载{{1}}时期望解析的额外数据。