阅读javamail需要很长时间

阅读javamail需要很长时间,java,jakarta-mail,Java,Jakarta Mail,我使用javamail通过IMAP协议从exchage帐户读取邮件。这些邮件是纯格式的,内容是XML 几乎所有这些邮件的大小都很短(通常小于100Kb)。然而,有时我不得不处理大型邮件(大约10Mb-15Mb)。例如,昨天我收到一封13Mb大小的电子邮件。仅仅读它就花了50多分钟。这正常吗?有没有办法提高它的性能? 代码是: Session sesion = Session.getInstance(System.getProperties()); Store store = sesion.get

我使用javamail通过IMAP协议从exchage帐户读取邮件。这些邮件是纯格式的,内容是XML

几乎所有这些邮件的大小都很短(通常小于100Kb)。然而,有时我不得不处理大型邮件(大约10Mb-15Mb)。例如,昨天我收到一封13Mb大小的电子邮件。仅仅读它就花了50多分钟。这正常吗?有没有办法提高它的性能? 代码是:

Session sesion = Session.getInstance(System.getProperties());
Store store = sesion.getStore("imap");
store.connect(host, user, passwd);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);

Message[] messages = inbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
for (int i = 0 ; i< messages.length ; i++){
    Object contents = messages[i].getContent();  // Here it takes 50 min on 13Mb mail
    // ...
}
会话sesion=Session.getInstance(System.getProperties()); Store Store=sesion.getStore(“imap”); store.connect(主机、用户、密码); 文件夹收件箱=store.getFolder(“收件箱”); 收件箱。打开(文件夹。读写); Message[]messages=inbox.search(新FlagTerm(新标志(Flags.Flag.SEEN),false)); for(int i=0;i 花费如此长时间的方法是
messages[i].getContent()
。我做错了什么?有什么提示吗


非常感谢,很抱歉我的英语

代码中最慢的部分总是messages[i].getContent()。原因通常是IMAP服务器不会缓存这部分消息数据。不过,您可以尝试以下方法:

    FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);
        fp.add(FetchProfileItem.FLAGS);
        fp.add(FetchProfileItem.CONTENT_INFO);
    fp.add("X-mailer");

and after you have specified the fetch profile then you do your search/fetch of messages. 
基本上,其概念是IMAP提供程序仅在必要时从服务器获取消息的数据。(javax.mail.FetchProfile用于优化此配置文件)。头和体结构信息一旦获取,总是缓存在消息对象中。但是,不会缓存bodypart的内容。因此,每次客户端请求内容时(使用getContent()或使用getInputStream()),都会向服务器发出一个新的获取请求。这是因为消息的内容可能很大,如果我们将此内容缓存为大量消息,则系统可能很快就会耗尽内存,因为垃圾收集器无法释放引用的对象。客户机应该意识到这一点,如果需要,必须保留检索到的内容


通过使用上面提到的代码片段,您可以“希望”提高一些速度,但这完全取决于您的SMTP服务器是否可以工作。由于上一段提到的加载问题,所有大型SMTP服务器都不支持此行为,因此您可能无法获得任何速度。

使用Folder.fetch方法,您可以在一次操作中预取多封邮件的元数据。这将减少处理每条消息的时间,但对于处理大量消息没有多大帮助

如果要高效地处理庞大的消息部分,通常需要使用getInputStream方法以增量方式处理数据,而不是使用getContent方法读取其中的所有数据并创建包含所有数据的庞大字符串对象


您还可以通过指定“mail.imap.fetchsize”属性(默认值为16384)来优化抓取。如果大多数邮件小于100K,并且您始终需要读取邮件中的所有数据,则可以将fetchsize设置为100K。这将使小消息更快,大消息更高效。

我终于解决了这个问题,并想与大家分享

这个解决方案,至少是对我有效的,在这个网站上找到了:

因此,我在第一篇文章中输入的原始代码变成:

Session sesion = Session.getInstance(System.getProperties());
Store store = sesion.getStore("imap");
store.connect(host, user, passwd);
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);

// Convert to MimeMessage after search 
MimeMessage[] messages = (MimeMessage[]) carpetaInbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
for (int i = 0 ; i< messages.length ; i++){
    // Create a new message using MimeMessage copy constructor
    MimeMessage cmsg = new MimeMessage(messages[i]);
    // Use this message to read its contents 
    Object obj = cmsg.getContent(); 
// ....
}
会话sesion=Session.getInstance(System.getProperties()); Store Store=sesion.getStore(“imap”); store.connect(主机、用户、密码); 文件夹收件箱=store.getFolder(“收件箱”); 收件箱。打开(文件夹。读写); //搜索后转换为mimessage MimeMessage[]messages=(MimeMessage[])ru毯ainbox.search(新FlagTerm(新标志(Flags.Flag.SEEN),false)); for(int i=0;i 诀窍是,使用mimessage()复制构造函数,创建一个新的mimessage并读取其内容,而不是原始消息。 您应该注意,这样的对象并没有真正连接到服务器,所以您对它所做的任何更改(如设置标志)都不会生效。对消息的任何更改都必须在原始消息上进行

总而言之:此解决方案可以读取使用IMAP协议连接到Exchange服务器的大型纯文本邮件(高达15Mb)。阅读13Mb邮件的时间从51-55分钟减少到9秒。难以置信


希望这能帮助别人,并为英语错误感到抱歉;)

我也有类似的问题。通过IMAP获取邮件的速度非常慢。此外,我在下载大型附件时遇到了另一个问题。查看后,我找到了中后面问题的解决方案,建议将
mail.imap.partialfetch
(分别
mail.imaps.partialfetch
)设置为
false
。这不仅解决了下载问题,还解决了邮件阅读速度慢的问题

在引用的JavaMail中,它是这样说的

  • 由于Microsoft Exchange IMAP服务器中存在问题,无法满足以下要求: 读取大消息时可能检索到的字节数。那里 有两种方法可以解决此Exchange错误:

    (a) Exchange IMAP服务器提供了一个名为 “快速消息检索”到UI。只需转到站点、服务器即可 或收件人,单击“IMAP4”选项卡和其中一个复选框 是“启用快速消息检索”。关掉它,八重奏开始了 计数将是准确的。这一点在

    (b) 将“mail.imap.partialfetch”属性设置为false。你会有 在提供给的Properties对象中设置此属性 你的会议

  • 某些IMAP服务器不实现