C# 构造多部分MIME消息而不将其保存在内存中

C# 构造多部分MIME消息而不将其保存在内存中,c#,mime,multipart,mimekit,C#,Mime,Multipart,Mimekit,我想用我从一些流中获得的部分数据(例如打开文件句柄)创建一个多部分MIME消息,并希望生成的多部分MIME消息通过流(例如作为HTTP连接一部分的网络端口)发送出去 但是,这些部分的大小有很多GB,所以我不想将它们保存在内存中,也不希望多部分MIME消息需要完全保存在内存中 那么,我如何创建多部分MIME消息而不将其保存在内存中,即在部分中进行流式传输,并让它“动态”地流式输出构造的消息呢 我想使用第三方MIME库,但不知道是否有任何支持这种流媒体,我不愿意自己编写 有什么推荐的做法吗?Mime

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

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

那么,我如何创建多部分MIME消息而不将其保存在内存中,即在部分中进行流式传输,并让它“动态”地流式输出构造的消息呢

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


有什么推荐的做法吗?

MimeKit支持从磁盘而不是从内存流式传输MimeParts的内容,但我不确定是否有任何HTTP库会为您提供原始套接字或网络流(或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);
message.WriteTo (stream);
您可以像这样创建多部分:

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);
message.WriteTo (stream);
您可以像这样将multipart设置为MimeMessage的主体(尽管我不确定您是否真的需要MimeMessage容器来完成您想要做的事情):

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

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);
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>获取多部分消息的流,直到多部分流需要时才读取部分流。这意味着(从监控进程大小来看),原始部分在任何时候都不会完全在内存中,多部分消息也不会完全在内存中。

唯一的方法是覆盖发送方法并在参数列表中包含文件名。不确定我是否做错了什么。。。我真的很想知道什么MIME库有这个流媒体功能,我把它作为一个问题发布了出来,但它作为一个建议请求被关闭了,所以我根据我的基本要求重新表述了这个问题,但这已经被否决了。我认为这是一个合理的问题,如果有一个现有的解决方案,我的问题,但我的措辞错误吗?这里有两个很好的链接。第一个是电子邮件()第3段说在mime附件之前需要两个“\r\n”。第二个是Wiki()。当您使用网络中的html库进行post时,您在调用方法之前附加了整个mime,这不是您想要的。是创建您自己的类来继承HttpWebRequest,以便您可以覆盖标准请求并添加您自己的方法以使用流进行post。@jdweng感谢您的建议和提示!我的问题的核心是真正的“任何mime库都已经这样做了”,答案似乎是我需要运行我自己的系统。
\r\n
是一个很好的提示。我实际上并不是通过HTTP发送它,所以可以处理这方面的问题。我所知道的唯一库是将xml作为字符串而不是流传递出去的。非常感谢,这正是我想要的:-)