如何解析电子邮件比OpenPop.dll更快
本文关键字:dll 更快 OpenPop 何解析 电子邮件 | 更新日期: 2023-09-27 18:09:48
可以使用OpenPop.dll。
Pop3Client objPOP3Client = new Pop3Client();
int intTotalEmail = 0;
DataTable dtEmail = new DataTable();
object[] objMessageParts;
try
{
dtEmail = GetAllEmailStructure();
if (objPOP3Client.Connected)
objPOP3Client.Disconnect();
objPOP3Client.Connect(strHostName, intPort, bulUseSSL);
try
{
objPOP3Client.Authenticate(strUserName, new Common()._Decode(strPassword));
intTotalEmail = objPOP3Client.GetMessageCount();
AddMapping();
for (int i = 1; i <= intTotalEmail; i++)
{
objMessageParts = GetMessageContent(i, ref objPOP3Client, dtExistMailList);
if (objMessageParts != null && objMessageParts[0].ToString() == "0")
{
AddToDtEmail(objMessageParts, i, dtEmail, dtUserList, dtTicketIDList, dtBlacklistEmails, dtBlacklistSubject, dtBlacklistDomains);
}
}
}
catch (Exception ex)
{
}
}
catch (Exception ex)
{
ParserLogError(ex, "GetAllEmail()");
}
finally
{
if (objPOP3Client.Connected)
objPOP3Client.Disconnect();
}
// function
public object[] GetMessageContent(int intMessageNumber, ref Pop3Client objPOP3Client, DataTable dtExistingMails)
{
object[] strArrMessage = new object[10];
Message objMessage;
MessagePart plainTextPart = null, HTMLTextPart = null;
string strMessageId = "";
try
{
strArrMessage[0] = "";
strArrMessage[1] = "";
strArrMessage[2] = "";
strArrMessage[3] = "";
strArrMessage[4] = "";
strArrMessage[5] = "";
strArrMessage[6] = "";
strArrMessage[7] = null;
strArrMessage[8] = null;
strArrMessage[7] = "";
strArrMessage[8] = "";
objMessage = objPOP3Client.GetMessage(intMessageNumber);
strMessageId = (objMessage.Headers.MessageId == null ? "" : objMessage.Headers.MessageId.Trim());
if (!IsExistMessageID(dtExistingMails, strMessageId)) //check in data base message id is exists or not
{
strArrMessage[0] = "0";
strArrMessage[1] = objMessage.Headers.From.Address.Trim(); // From EMail Address
strArrMessage[2] = objMessage.Headers.From.DisplayName.Trim(); // From EMail Name
strArrMessage[3] = objMessage.Headers.Subject.Trim();// Mail Subject
plainTextPart = objMessage.FindFirstPlainTextVersion();
strArrMessage[4] = (plainTextPart == null ? "" : plainTextPart.GetBodyAsText().Trim());
HTMLTextPart = objMessage.FindFirstHtmlVersion();
strArrMessage[5] = (HTMLTextPart == null ? "" : HTMLTextPart.GetBodyAsText().Trim());
strArrMessage[6] = strMessageId;
List<MessagePart> attachment = objMessage.FindAllAttachments();
strArrMessage[7] = null;
strArrMessage[8] = null;
if (attachment.Count > 0)
{
if (attachment[0] != null && attachment[0].IsAttachment)
{
strArrMessage[7] = attachment[0].FileName.Trim();
strArrMessage[8] = attachment[0];
}
}
}
else
{
strArrMessage[0] = "1";
}
}
catch (Exception ex)
{
ParserLogError(ex, "GetMessageContent()");
}
return strArrMessage;
}
但是,我想使它比上面的OpenPop.dll更快。所以,如果有其他的技术可以解析邮件,请告诉我。
请核对代码后告诉我。
Thanks in advance
但是,我想使它比上面的OpenPop.dll更快。所以请让我了解是否有其他技术可以解析邮件。
在GetMessageContent()方法中,消耗大量时间的一个地方是:
objMessage = objPOP3Client.GetMessage(intMessageNumber);
下载消息的网络I/O部分无法真正优化,但是OpenPop。. NET的解析器很慢(基于我自己的性能测试)。
MimeKit比OpenPop快25倍。. NET解析电子邮件消息
OpenPop的主要性能问题之一。. NET的MIME解析器是使用StreamReader进行解析的事实(由于不必要的字符集转换,一次读取一行等,它很慢-我在这里分析了另一个使用StreamReader进行解析的电子邮件库:https://stackoverflow.com/a/18787176/87117)。
还有OpenPop的问题。. NET的解析器还使用Regex在解析/解码头字符串之前从头字符串中删除CFWS(注释和折叠空白)。这很贵。最好编写一个能够处理CFWS的标记器。
如果你对我用来优化MimeKit的其他一些技术感兴趣(与高度优化的C实现一样快或更快),我写了一些关于这个的博客文章:
MimeKit使用的优化技巧:第1部分
我在第一部分中谈到的优化的总结是替换像这样的循环,扫描一行的末尾:
while (*inptr != (byte) ''n')
inptr++;
和一个更快的循环,像这样:
int* dword = (int*) inptr;
do {
mask = *dword++ ^ 0x0A0A0A0A;
mask = ((mask - 0x01010101) & (~mask & 0x80808080));
} while (mask == 0);
inptr = (byte*) (dword - 1);
while (*inptr != (byte) ''n')
inptr++;
提高了20%的性能(尽管在非x86架构上,它要求'dword'是4字节对齐的)。
MimeKit使用的优化技巧:第2部分
在第2部分中,我讨论了如何编写一个更加优化的System.IO.MemoryStream版本。MemoryStream的问题是,它必须保持一个连续的内存块与内容,这意味着,当你写更多的数据到它,它必须调整其内部字节数组的大小,它必须复制的内容到新的数组(这是昂贵的,特别是一旦数据量在流很大)。为了解决这个性能瓶颈,我编写了一个MemoryBlockStream,它不需要使用连续的内存块-它使用字节数组的链表。当当前缓冲区溢出时,它不必重新调整字节数组的大小,而是简单地分配另一个2048字节的数组,数据将溢出并将其附加到链表中。
注意:MimeKit本身只做电子邮件解析,它不做POP3或SMTP或IMAP。如果你想要这种功能,我也写了一个基于MimeKit的库,它也能做到这一点:MailKit
更新:
使用MailKit(按要求)下载/解析所有消息的示例代码:
using System;
using System.Net;
using MailKit.Net.Pop3;
using MailKit;
using MimeKit;
namespace TestClient {
class Program
{
public static void Main (string[] args)
{
using (var client = new Pop3Client ()) {
client.Connect ("pop.gmail.com", 995, true);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove ("XOAUTH2");
client.Authenticate ("joey@gmail.com", "password");
int count = client.GetMessageCount ();
for (int i = 0; i < count; i++) {
var message = client.GetMessage (i);
Console.WriteLine ("Subject: {0}", message.Subject);
}
client.Disconnect (true);
}
}
}
}