MIME,英文全称为"Multipurpose Internet Mail Extensions",即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范。在MIME出现之前,互联网电子邮件主要遵循由RFC 822所制定的标准,电子邮件一般只用来传递基本的ASCII码文本信息,MIME在 RFC 822的基础上对电子邮件规范做了大量的扩展,引入了新的格式规范和编码方式,在MIME的支持下,图像、声音、动画等二进制文件都可方便的通过电子邮件来进行传递,极大地丰富了电子邮件的功能。目前互联网上使用的基本都是遵循MIME规范的电子邮件。
表1是一封示例邮件的内容,其中行1-5、行8都是单行的域,行6-7则是一个多行的域,并带有一个名为charset的属性,属性值为us-ascii。
行1 From: "suntao" <suntao@fimmu.com> 行2 To: <yxj@fimmu.com> 行3 Subject: hello world 行4 Date: Mon, 9 Oct 2006 16:51:34 +0800 行5 MIME-Version: 1.0 行6 Content-Type: text/plain; 行7 charset="us-ascii" 行8 Date: Mon, 9 Oct 2006 16:48:25 +0800 行9 行10 Hello world 行11 |
邮件规范中定义了大量域,分别用来存储同邮件相关的各种信息,比如发件人的名字和邮件地址信息存储在From域中,收件人的邮件地址信息存储在To域中,开发人员可通过查询RFC文档得到完整的邮件域定义列表。
示例邮件中的行6-7就是一个Content-Type域,主类型为text,子类型为plain,字符集属性为us-ascii。
主类型 | 常见属性 | 参数含义 |
text | charset | 文本信息所使用的字符集 |
image | name | 图像的名称 |
application | name | 应用程序的名称 |
multipart | boundary | 邮件分段边界标识 |
Content-Type: multipart/mixed;
Content-Type: multipart/alternative;
Content-Type: multipart/related;
Multipart/mixed | ||||||
| ||||||
附件 |
1.4 Content-Transfer-Encoding域
下面给出.Net环境下,利用C#结合正则表达式从邮件中提取相关信息的基本思路和部分代码。
收件人、发件人、邮件主题是一封邮件的基本组成信息,分别存邮件的From域、To域、Subject域中。开发中只需要通过正则表达式来匹配这些指定的域,然后从匹配结果中取出相关信息即可。
string emailContent = "……";//emailContent中存储的是邮件内容
pat = @"^Subject:s*(?<title>.*)s* ";
myMatches = Regex.Matches(emailContent,pat,RegexOptions.Multiline);
foreach(Match nextMatch in myMatches)
GroupCollection myGroup = nextMatch.Groups;
string title = myGroup["title"].ToString();//title变量存储From域的内容
string emailContent = "……";//emailContent中存储的是邮件内容
string pat = @"Content-Type:s*(?<type>w+/w+);s+(type=S(?<subtype>S+)S)?s+boundary=""(?<flag>S+)""";
MatchCollection myMatches = Regex.Matches(emailContent,pat);
foreach(Match nextMatch in myMatches)
GroupCollection myGroup = nextMatch.Groups;
string type = myGroup["type"].ToString();//type变量存储multipart类型的名称
string flag = myGroup["flag"].ToString();//flag变量存储multipart类型的boundary属性
--boundary分段标识 Content-Type: application/msword; name="readme.doc" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=" readme.doc " …… 文件内容的Base64编码 …… --boundary分段标识 |
//boundaryMixed代表已经提取出的multipart/mixed类型的boundary标识
//DecodeQuotedPrintable为自定义的quoted-printable解码函数
string emailContent = "……";//emailContent中存储的是邮件内容
MatchCollection myMatches = Regex.Matches(emailContent,pat,RegexOptions.Singleline);
foreach(Match nextMatch in myMatches)
GroupCollection myGroup = nextMatch.Groups;
string fileType = myGroup["filetype"].ToString();
string encoding = myGroup["encoding"].ToString();
string fileName = myGroup["filename"].ToString();
string content = myGroup["content"].ToString().Trim();
attachFile = DecodeBase64 (content);
if(encoding == "quoted-printable")
attachFile = DecodeQuotedPrintable (content);
FileStream fs = new FileStream("c:\" + fileName,
BinaryWriter bw = new BinaryWriter(fs);
上面的程序从邮件原文中提取出附件信息,并根据附件采用的编码类型进行解码,然后将解码后的内容按照原文件名存储到C盘根目录。同样,如果附件的文件名是中文或者其它需要编码的文字,则首先需要对文件名进行解码。