You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MailKit获取MimeMessage对象完整内容长度的方法咨询

关于MailKit中MimeMessage预获取发送内容长度的解答

目前MailKit库没有原生提供无需序列化即可直接获取MimeMessage完整发送内容长度的API。因为MIME邮件的最终发送内容包含动态生成的头字段、编码后的正文、附件边界标识、换行符标准化等多部分动态内容,无法在不执行序列化逻辑的前提下100%准确计算总长度。

你当前设计的实现方案存在两处明显问题:

  • 仅统计了Body部分的大小,没有包含邮件头(发件人、收件人、主题、自定义头、MIME版本声明等)的长度,计算结果会比实际发送的总大小小很多
  • 不需要将序列化后的字节转Base64再计算长度:MemoryStream.Length本身就已经是序列化后的字节总数,转Base64会让计算结果比实际值大33%左右,完全不符合实际大小统计需求

低内存占用优化方案(推荐)

你可以实现一个仅计数不实际存储数据的虚拟流,避免将整个邮件内容加载到内存中,开销几乎可以忽略,同时能拿到准确的总长度:

// 仅计数的虚拟流,不实际存储字节数据
public class DummyCountStream : Stream
{
    public long TotalBytesWritten { get; private set; }

    public override void Write(byte[] buffer, int offset, int count)
    {
        TotalBytesWritten += count;
    }

    public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
    {
        TotalBytesWritten += count;
        return Task.CompletedTask;
    }

    // 其余Stream抽象成员无需实现,MimeMessage序列化仅会调用Write/WriteAsync方法
    public override bool CanRead => false;
    public override bool CanSeek => false;
    public override bool CanWrite => true;
    public override long Length => throw new NotImplementedException();
    public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
    public override void Flush() { }
    public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException();
    public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();
    public override void SetLength(long value) => throw new NotImplementedException();
}

使用方式如下:

var counter = new DummyCountStream();
// 调用整个MimeMessage的序列化方法,而非仅序列化Body
await mailMessage.WriteToAsync(counter);
// 得到的长度即为实际发送的邮件总字节数
long curMessageLength = counter.TotalBytesWritten;

如果不想额外实现虚拟流,也可以用简化版的正确写法:

using (var memory = new MemoryStream())
{
    await mailMessage.WriteToAsync(memory);
    long curMessageLength = memory.Length;
}

该方案仅会在内存中临时存储整份邮件内容,对于常规大小的邮件开销在可接受范围内。

内容的提问来源于stack exchange,提问作者Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:45:02