导航 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的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序页面导航详解

如何同时使用导航抽屉和底部导航 - 导航架构组件

使用底部导航栏导航回页面时颤动通过底部导航栏选择的索引

制作导航栏棒

TabBarViewController 的导航栏覆盖来自导航控制器的导航栏

高德导航怎么用 怎样使用高德地图进行导航