C# 在C中读取mbox文件#
我们的一名员工丢失了他的邮箱,但幸运的是他有一封mbox格式的邮件。我需要以某种方式获取mbox文件中的所有消息,并将它们喷射到我们的技术支持数据库中(因为它是一个自定义工具,没有可用的导入工具) 我发现它可以分解一条消息,但不允许您在mbox文件中遍历一堆消息C# 在C中读取mbox文件#,c#,email,mime,mbox,C#,Email,Mime,Mbox,我们的一名员工丢失了他的邮箱,但幸运的是他有一封mbox格式的邮件。我需要以某种方式获取mbox文件中的所有消息,并将它们喷射到我们的技术支持数据库中(因为它是一个自定义工具,没有可用的导入工具) 我发现它可以分解一条消息,但不允许您在mbox文件中遍历一堆消息 有没有人知道一个不需要学习RFC就可以编写出来的语法分析器呢?我不知道任何语法分析器,但是mbox确实是一种非常简单的格式。一封新的电子邮件以“From”(From+空格)开头,每封邮件的末尾都会附加一个空行。如果在电子邮件本身的行首出
有没有人知道一个不需要学习RFC就可以编写出来的语法分析器呢?我不知道任何语法分析器,但是mbox确实是一种非常简单的格式。一封新的电子邮件以“From”(From+空格)开头,每封邮件的末尾都会附加一个空行。如果在电子邮件本身的行首出现“From”,则会将其引用(通过在“>”前面加上前缀)
另请参见。如果您可以扩展到使用Python,则标准库中有。遗憾的是,我找不到任何适用于.NET的语法分析器。我正在用C语言编写一个名为MIME&mbox的语法分析器 它基于我以前编写的MIME和mbox解析器(例如),速度非常快(可以在大约1秒内解析1.2GB mbox文件中的每条消息) 我还没有测试MimeKit的性能,但我在C中使用了许多与我在C中使用的相同的技术。我怀疑它会比我的C实现慢,但由于瓶颈是I/O,而且MimeKit是为了像GMime一样进行最佳(4k)读取而编写的,所以它们应该非常接近 您发现当前方法速度慢的原因(StreamReader.ReadLine(),组合文本,然后将其传递给SharpMimeTools)是因为以下原因:
using (var stream = File.OpenRead ("Inbox.mbox")) {
var parser = new MimeParser (stream, MimeFormat.Mbox);
while (!parser.IsEndOfStream) {
var message = parser.ParseMessage ();
// At this point, you can do whatever you want with the message.
// As an example, you could save it to a separate file based on
// the message subject:
message.WriteTo (message.Subject + ".eml");
// You also have the ability to get access to the mbox marker:
var marker = parser.MboxMarker;
// You can also get the exact byte offset in the stream where the
// mbox marker was found:
var offset = parser.MboxMarkerOffset;
}
}
2013年9月18日更新:我已经让MimeKit达到了可以用来解析mbox文件的地步,并且成功地解决了问题,但它的速度远不及我的C库。这是在iMac上测试的,因此I/O性能不如在我的旧Linux机器上(GMime可以在1秒内解析大小类似的mbox文件):
正如您所看到的,GMime仍然要快一点,但是我对如何提高MimeKit解析器的性能有一些想法。原来C#的fixed
语句非常昂贵,所以我需要重新使用它们。例如,我昨天剃了大约2-3秒的胡子(如果我没记错的话)
优化更新:通过替换以下内容,性能又提高了20%:
while (*inptr != (byte) '\n')
inptr++;
与:
优化更新:我最终能够通过切换使用Enum.HasFlag()而改用直接位屏蔽,使MimeKit的速度与GMime一样快
MimeKit现在可以在3.78秒内解析相同的mbox流
相比之下,SharpMimeTools需要20多分钟(为了测试这一点,我不得不将电子邮件拆分为单独的文件,因为SharpMimeTools无法解析mbox文件)
另一个更新:通过代码中的各种其他调整,我将其降到了3.00s平面。要读取.mbox文件,可以使用第三方库。 这个图书馆是一个完整的图书馆
while (*inptr != (byte) '\n')
inptr++;
do {
mask = *dword++ ^ 0x0A0A0A0A;
mask = ((mask - 0x01010101) & (~mask & 0x80808080));
} while (mask == 0);
inptr = (byte*) (dword - 1);
while (*inptr != (byte) '\n')
inptr++;
using(FileStream stream = new FileStream("ExampleMbox.mbox", FileMode.Open, FileAccess.Read))
{
using(MboxrdStorageReader reader = new MboxrdStorageReader(stream, false))
{
// Start reading messages
MailMessage message = reader.ReadNextMessage();
// Read all messages in a loop
while (message != null)
{
// Manipulate message - show contents
Console.WriteLine("Subject: " + message.Subject);
// Save this message in EML or MSG format
message.Save(message.Subject + ".eml", SaveOptions.DefaultEml);
message.Save(message.Subject + ".msg", SaveOptions.DefaultMsgUnicode);
// Get the next message
message = reader.ReadNextMessage();
}
}
}