Skip to main content

4. Data Formats (数据格式)

IMAP4rev1 使用文本命令和响应. IMAP4rev1 中的数据可以采用几种形式之一: 原子 (Atom), 数字 (Number), 字符串 (String), 括号列表 (Parenthesized List) 或 NIL. 请注意, 特定数据项可能采用多种形式, 例如, 定义为使用 "astring" 语法的数据项可以是原子或字符串.

4.1. Atom (原子)

原子由一个或多个非特殊字符组成.

示例:

OK
INBOX
CAPABILITY

4.2. Number (数字)

数字由一个或多个数字字符组成, 表示数值.

示例:

1
42
1234

4.3. String (字符串)

字符串有两种形式之一: 字面量 (Literal) 或引号字符串 (Quoted String). 字面量形式是字符串的一般形式. 引号字符串形式是一种替代方案, 它避免了处理字面量的开销, 代价是限制了可以使用的字符.

字面量 (Literal)

字面量是零个或多个八位字节 (包括 CR 和 LF) 的序列, 前缀引用八位字节计数, 形式为左大括号 ({), 八位字节数, 右大括号 (}), 和 CRLF.

  • 服务器到客户端: CRLF 后紧跟八位字节数据
  • 客户端到服务器: 客户端必须 (MUST) 等待接收命令继续请求 (Command Continuation Request, 本文档后面描述) 后再发送八位字节数据 (和命令的其余部分)

示例:

{12}
Hello World!

{0}
(空字面量)

引号字符串 (Quoted String)

引号字符串是零个或多个 7 位字符的序列, 不包括 CR 和 LF, 每端都有双引号 (") 字符.

示例:

"Hello"
"INBOX"
"[email protected]"

空字符串

空字符串表示为:

  • "" (双引号之间没有字符的引号字符串)
  • {0} 后跟 CRLF (八位字节计数为 0 的字面量)

注意: 即使八位字节计数为 0, 传输字面量的客户端也必须 (MUST) 等待接收命令继续请求.

4.3.1. 8-bit and Binary Strings (8位和二进制字符串)

通过使用 [MIME-IMB] 内容传输编码支持 8 位文本和二进制邮件. IMAP4rev1 实现可以 (MAY) 在字面量中传输 8 位或多八位字节字符, 但应该 (SHOULD) 仅在识别 [CHARSET] 时才这样做.

虽然定义了 BINARY 正文编码, 但不允许未编码的二进制字符串. "二进制字符串" 是任何带有 NUL 字符的字符串. 实现必须 (MUST) 在传输数据之前将二进制数据编码为文本形式, 例如 BASE64. 具有过多 CTL 字符的字符串也可以 (MAY) 被视为二进制.

4.4. Parenthesized List (括号列表)

数据结构表示为 "括号列表", 一系列由空格分隔的数据项, 并在每端由括号括起来. 括号列表可以包含其他括号列表, 使用多级括号表示嵌套.

示例:

(FLAGS (\Seen \Answered))
(1 2 3 4 5)
(BODY ("TEXT" "PLAIN" ("CHARSET" "US-ASCII") NIL NIL "7BIT" 1152 23))

空列表表示为 () - 没有成员的括号列表.

4.5. NIL

特殊形式 "NIL" 表示特定数据项 (表示为字符串或括号列表) 的不存在, 与空字符串 "" 或空括号列表 () 不同.

注意: NIL 从不用于采用原子形式的任何数据项. 例如, 邮箱名称 "NIL" 是名为 NIL 的邮箱, 而不是不存在的邮箱名称. 这是因为邮箱使用 "astring" 语法, 它是原子或字符串. 相反, addr-name 为 NIL 是不存在的个人姓名, 因为 addr-name 使用 "nstring" 语法, 它是 NIL 或字符串, 但从不是原子.


数据格式对比表

格式定义示例用途
Atom (原子)非特殊字符序列INBOX, OK, FLAGS命令名, 关键字, 简单标识符
Number (数字)数字字符序列1, 42, 1234消息序列号, 计数, UID
Quoted String (引号字符串)双引号包围的字符"Hello", "[email protected]"简单文本, 邮箱名称
Literal (字面量){n}CRLF + n个八位字节{12}CRLF + Hello World!包含特殊字符的文本, 二进制数据
Parenthesized List (括号列表)括号包围的项列表(1 2 3), (FLAGS (\Seen))复杂数据结构, 嵌套信息
NIL特殊值表示不存在NIL表示缺少的可选字段

字符串格式选择指南

使用引号字符串的情况:

  • ✅ 简单 ASCII 文本
  • ✅ 不包含双引号, CR, LF 的字符串
  • ✅ 短字符串 (性能考虑)

使用字面量的情况:

  • ✅ 包含双引号, CR, LF 的字符串
  • ✅ 8位或多字节字符
  • ✅ 二进制数据 (BASE64 编码后)
  • ✅ 大量文本

实际示例

示例 1: FETCH 响应中的数据格式

* 1 FETCH (
FLAGS (\Seen) # 括号列表
UID 4827313 # 数字
INTERNALDATE "17-Jul-1996 02:44:25 -0700" # 引号字符串
RFC822.SIZE 4286 # 数字
BODY[HEADER.FIELDS (FROM)] {21} # 字面量
From: [email protected] # 字面量内容
)

示例 2: LIST 响应

* LIST (\Noselect) "/" ~/Mail/foo   # 原子: \Noselect, 引号字符串: "/"
* LIST () NIL INBOX # 空列表: (), NIL, 原子: INBOX

示例 3: SEARCH 响应

* SEARCH 1 2 3 4 5                  # 所有都是数字
* SEARCH # 没有匹配 (空结果)

术语表 (本章重点术语):

  • Atom (原子): 不包含特殊字符的简单字符序列
  • Number (数字): 数值的文本表示
  • String (字符串): 文本数据, 可以是引号字符串或字面量
  • Literal (字面量): 带前缀长度的字符串, 支持任意八位字节
  • Quoted String (引号字符串): 双引号包围的 7 位字符串
  • Parenthesized List (括号列表): 括号包围的数据项列表
  • NIL: 表示数据项不存在的特殊值
  • astring: 可以是原子或字符串的语法类型
  • nstring: 可以是 NIL 或字符串的语法类型