构造一个多部分MIME消息,而不将其保存在内存中



我想用一些流中可用的部分数据创建一个多部分MIME消息(例如打开文件句柄(,并希望通过流(例如作为HTTP连接一部分的网络端口(发送得到的多部分MIME信息。

然而,这些部分的大小是许多GB,所以我不想将它们保存在内存中,也不希望多部分MIME消息需要完全存储在内存中。

那么,我如何在不将其保存在内存中的情况下创建多部分MIME消息,即在多个部分中进行流式传输,并让它"动态"地输出构建的消息呢?

我想使用第三方MIME库,但不知道是否有人支持这样的流媒体,我不愿意自己编写。

有什么推荐的做法吗?

MimeKit支持从磁盘而不是从内存流式传输MimeParts的内容,但我不确定是否有任何HTTP库会为您提供原始套接字或NetworkStream(或SslStream(来写入消息。

假设HTTP库不是一个限制因素,您可以在MimeKit中创建MimeParts,如下所示:

var part = new MimePart ("application", "octet-stream") {
Content = new MimeContent (File.OpenRead ("large-file.dat")),
ContentTransferEncoding = ContentENcoding.Base64,
FileName = "large-file.dat"
};

您可以创建这样的多部分:

var multipart = new Multipart ("mixed");
multipart.Add (part);

你可以像这样将多部分设置为MimeMessage的主体(尽管我不确定你是否真的需要MimeMessage容器来完成你想要做的事情(:

message.Body = multipart;

您可以将消息(或多部分(流式传输到网络流(或任何类型的流(,如下所示:

message.WriteTo (stream);

如果你需要确保即使在Unix系统上也能将消息转换为使用CRLF,你可以这样做:

var options = FormatOptions.Default.Clone ();
options.NewLineFormat = NewLineFormat.Dos;
message.WriteTo (options, stream);

这将推动消息数据通过一个过滤器,该过滤器将在将行结尾写入输出流时转换行结尾(如果需要转换(。

由于消息数据分块存储在大约4k个块中,因此它应该符合您的要求。

如果你还有其他问题,请在GitHub上找到我的电子邮件地址(化名相同,我是MimeKit/MailKit的作者,所以我应该很容易找到(,然后给我发一封电子邮件。我很乐意回答你关于如何做到这一点的任何问题。

事实上,MimeKit的设计目的是做你想做的事情,并确保一切正常,我写了MailKit的原始SmtpClient。然后,我在之后的周末编写了Pop3Client,以测试我是否可以解析直接从套接字读取的消息。

所以,是的,它可以做你需要它做的事情。

经过进一步研究(受上面MimeKit示例的启发(,.Net HTTP类以类似于MimeKit的方式支持我所寻找的内容。

创建一个MultipartContent并使用StreamContent添加部分,然后使用MultipartContent.ReadAsStreamAsync为多部分消息获取一个流,直到多部分流需要它时才读取部分流。这意味着(从监控进程大小来看(原始部分在任何时候都不会完全在内存中,多部分消息也不会。

最新更新