导航 MimeKit.MimeParser

Navigating MimeKit.MimeParser

是否可以使用 MimeKit.MimeParser 从 mbox 文件中读取第 M 封邮件的第 N 个附件?就我而言,我会将几条消息(每个消息的几个字段,包括附件列表)存储到内存中的数据结构中,之后,我希望能够 return 到特定的消息附件并阅读它的内容。

到目前为止我尝试过的事情:

上面的不行。

这里有一些代码只是为了说明我的努力:

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);
     }
}

Is it possible to read the Nth attachment of the Mth message, from an mbox file, using MimeKit.MimeParser?

如果你想这样做,那么你将需要你想要的 MimeEntity 的精确流 start/end 偏移量。

然后您要做的是使用这些流偏移将流包装在 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

I want to be able to return to a specific message attachment and read its contents.

您是否查看了 MimeParser.SetStream() 的 persistent 参数?

这可能仍然使用比您想要使用的更多的内存(因为它将加载所有 headers + 每个 MimeEntity 内容的轨道流偏移),但您可能会发现它更方便并且具有low-enough 内存使用量以满足您的实际需要。

当此 属性 设置为 true 时,它不会将每个 MimePart 的内容加载到 RAM 中,而是创建一个 BoundStream 来包装提供给 MimeParser 的流,以便在您请求内容时这些 MimeParts,它从磁盘延迟加载它。

默认情况下(或当 persistent = false 时),MimeParser 会将内容加载到 MemoryBlockStream(实际上是一个试图减少字节数组大小调整以提高性能的 MemoryStream),正如您可能知道的那样,它可以使用相当如果邮件有大附件(或很多附件),需要一点内存。

使用 persistent = true 时需要注意的一点是,如果您希望能够获取解析器解析的任何 MimePart 的内容,则需要保持 mbox 文件流处于打开状态。关闭流后,尝试获取任何 MimePart 的内容可能会导致 ObjectDisposedException。