导航 MimeKit.MimeParser
Posted
技术标签:
【中文标题】导航 MimeKit.MimeParser【英文标题】:Navigating MimeKit.MimeParser 【发布时间】:2021-10-04 04:57:33 【问题描述】:是否可以使用 MimeKit.MimeParser 从 mbox 文件中读取第 M 条消息的第 N 个附件?就我而言,我会将少量消息(每个消息的几个字段,包括附件列表)存储到内存数据结构中,之后,我希望能够返回到特定的消息附件并阅读其内容。
到目前为止我尝试过的事情:
记住每条已读消息的底层流位置,并 在调用之前将流定位到该位置 _parser.ParseMessage() 稍后获取消息及其附件。 我还尝试使用 LINQ 方法通过以下方式获取消息 MessageID 结合将流位置设置为 0 和 在没有它的情况下再次调用 SetStream。上述方法不起作用。
这里有一些代码只是为了说明我的努力:
public void SaveAttachment(Attachment att, Stream outStream)
_inputStream.Seek(0, SeekOrigin.Begin);
_parser.SetStream(_inputStream, false);
//MimeMessage mimeMsg = _parser.Skip((int)(att.Parent as Message).Position).First();
MimeMessage mimeMsg =_parser.SingleOrDefault(x => x.MessageId == (att.Parent as Message).EntryID);
MimeEntity mimeAtt = mimeMsg.Attachments.ToList()[att.AttachmentIndex];
if (mimeAtt is MessagePart)
(mimeAtt as MessagePart).Message.WriteTo(outStream);
else
(mimeAtt as MimePart).Content.DecodeTo(outStream);
【问题讨论】:
【参考方案1】:是否可以使用 MimeKit.MimeParser 从 mbox 文件中读取第 M 条消息的第 N 个附件?
如果您想这样做,那么您将需要您想要的 MimeEntity 的确切流开始/结束偏移量。
然后您要做的是将流包装在 MimeKit.IO.BoundStream 中,并使用这些流偏移量来防止解析器偏离这些边界并在 MimeParser 上设置 BoundStream。
设置流时,请确保使用MimeFormat.Entity
(不是MimeFormat.Mbox
),因为您只对解析单个MimeEntity
(可以是包含其他MimeEntities)。
要获得这些偏移量,您需要在首次解析 mbox 时订阅 MimeParser 的 MimeEntityBegin/End 事件:http://www.mimekit.net/docs/html/Events_T_MimeKit_MimeParser.htm
我希望能够返回到特定的邮件附件并阅读其内容。
您是否查看过 MimeParser.SetStream() 的 persistent
参数?
这可能仍然使用比您想要使用的更多的内存(因为它将加载所有标题 + 跟踪每个 MimeEntity 内容的流偏移),但您可能会发现它更方便并且内存使用量足够低满足您的实际需求。
当此属性设置为true
时,它不会将每个 MimePart 的内容加载到 RAM 中,而是创建一个 BoundStream 来包装提供给 MimeParser 的流,以便当您请求这些 MimePart 的内容时,它会延迟加载它从磁盘。
默认情况下(或persistent = false
),MimeParser 会将该内容加载到 MemoryBlockStream(实际上是一个尝试减少字节数组大小以提高性能的 MemoryStream),正如您可能知道的那样,它可以使用相当多的内存如果邮件有大附件(或很多附件)。
使用persistent = true
时要注意的是,如果您希望能够获取解析器解析的任何 MimePart 的内容,则需要保持 mbox 文件流打开。关闭流后,尝试获取任何 MimePart 的内容可能会导致 ObjectDisposedException。
【讨论】:
谢谢@jstedfast。 MimeMessageEndEventArgs 包含 EndOffset 和 BeginOffset,因此似乎不需要 MimeMessageBegin 事件处理程序。以上是关于导航 MimeKit.MimeParser的主要内容,如果未能解决你的问题,请参考以下文章