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

不使用javax.Mail如何计算fetch RFC822.SIZE字段值

RFC 1064 协议下 FETCH 命令 RFC822.SIZE 字段计算方法

字段本质定义

RFC822.SIZE的取值是符合RFC822规范的完整邮件原始报文的字节总数,这个值是给客户端做邮件大小展示、下载进度计算、断点续传偏移判断用的,要求精度100%,不能有字节级误差。

具体实现规则

  • 计数基准为纯RFC822邮件报文的二进制字节流,覆盖范围必须包含三部分:
    1. 完整的邮件头区域(所有头字段、头字段内部的折叠换行都要算)
    2. 邮件头和正文之间的空分隔行(即单独的\r\n行)
    3. 完整的邮件正文区域(包含所有MIME分段头、MIME边界分隔符、base64/Quoted-Printable编码后的附件内容、最后一级MIME的结束边界--xxx--)
  • 必须避开的错误计算逻辑:
    • 不要对原始报文做任何转码、解码、内容裁剪后计数:比如不要把base64附件解码成原文件算大小,不要删除冗余头字段,不要去掉MIME分隔线
    • 不要把你的服务端自定义存储的元数据算进去:比如你在数据库里给邮件加的UID、存储路径、用户标签这类非RFC822标准的内容,全部排除
    • 不要按字符数计数:多字节编码(比如UTF-8的中文头、中文正文)要按实际占用的字节数算,不能按Unicode字符个数算
  • 换行符特殊处理
    IMAP协议要求邮件传输统一使用CRLF(\r\n,即字节0x0D 0x0A)作为换行符:
    • 如果你存储的邮件原始流本身就是标准CRLF换行,直接返回流的总字节数即可
    • 如果你存储时做了空间优化,把所有CRLF归一化成了单个LF(\n,字节0x0A),返回SIZE前要补算所有LF对应的CR字节长度,公式为:最终SIZE = LF格式存储的报文总字节数 + 报文中LF字符的总个数

参考实现伪代码

/**
 * 计算RFC822.SIZE返回值
 * @param rawStoredMail 服务端存储的原始邮件二进制字节
 * @param isCrlfStored  存储时是否使用标准CRLF换行
 * @return 符合RFC1064要求的RFC822.SIZE值
 */
long calcRfc822Size(byte[] rawStoredMail, boolean isCrlfStored) {
    if (isCrlfStored) {
        return rawStoredMail.length;
    }
    // 统计LF数量补算CR字节
    long lfCnt = 0;
    for (byte b : rawStoredMail) {
        if (b == 0x0A) {
            lfCnt++;
        }
    }
    return rawStoredMail.length + lfCnt;
}

校验标准

你实际通过FETCH命令返回完整RFC822报文内容时,传输的邮件实体总字节数必须和你返回的RFC822.SIZE值完全相等,否则客户端会判定报文截断、解析失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:36:20