当前位置: 首页 > 面试题库 >

JavaMail,IMAP,具有大量文件夹的性能

高钱青
2023-03-14
问题内容

我们正在为IMAP帐户开发基于Java的邮件客户端,并使用最新的Java邮件api(1.5.6)。我们的客户拥有超过400个文件夹的邮件帐户。用户在文件夹上执行检查邮件,并在每个文件夹上进行迭代并获取新消息,例如,

folder.getMessagesByUid(lastStoredUID, UIDFolder.LastUID)

或获取未读邮件的数量过多,这是因为文件夹数量巨大。(我们必须遍历400个文件夹)

为了提高性能,我们在线程中使用了并行工作连接,并且我们有一个SESSION实例,但是每个线程(连接)都有自己的STORE实例。当我们必须提取新消息时,我们会即时生成10个线程及其STORE实例,分别连接/登录它们,在该STORE上获取文件夹实例,打开文件夹,执行文件夹操作,然后关闭文件夹并关闭SESSION。但是对我来说,尚不清楚我是否必须保留文件夹实例,也不清楚
该文件夹是否应该保持打开状态,还是应该向后明确关闭,还是可以保留所有打开状态 (将关闭操作留给mailserver)。

在我目前的实现中

    new Thread() {
        public void run() {
            //Get a new store instance
            Store tempStore = MySingleSession.getStore("imap");
            tempStore.connect(..);

            //Get a folder for example inbox
            Folder inbox = tempStore.get("INBOX");

            inbox.open(Folder.READ);

            // Perform get new messages
            inbox.getMessagesByUd(lastUID, UIDFolder.MaxUID);

            inbox.close();

            tempStore.close();
            ..

当检查性能时,我发现打开/关闭文件夹需要很长时间,尤其是对于包含100.000条以上消息的文件夹。而且我发现,即使我关闭了文件夹的存储,该文件夹仍保持打开状态,并且如果不显式关闭该文件夹,我们可以对其进行操作。如果更改实现而不显式关闭文件夹并使之保持打开状态,则这种机制的缺点是什么?

  • 将文件夹引用保留在以其全名作为键的哈希表中,例如“ INBOX”-> IMAPFolder,并在执行任何操作(getMessages)之前执行isOpened检查,但是完成后,请不要像我当前的实现中那样显式关闭。这样做时,我们可能已经打开了400个文件夹,这对于邮件服务器和关闭邮件服务器来说似乎很糟糕,但是我将首先检查每个文件夹的运行情况(是否打开)。结果,文件夹将保持打开状态(直到mailserver关闭连接),如果再次需要相同的文件夹,则不必再次打开该文件夹。

  • 我不明白,为什么我仍然可以在已关闭存储的文件夹上进行操作?

  • mail.imap.connectionpoolsize的 默认值为1,在这种情况下是否有助于增加此值?

  • 我不明白下面这种情况会发生什么?

        Store tempStore = MySingleSession.getStore("imap");

    tempStore.connect(..);

    Folder f = tempStore.getFolder("INBOX");

    f.open(Folder.READ_ONLY);

    // close the store!!!
    tempStore.close();

    // now folder f becomes closed,
    // but we may open it again even if its Store is disconnected!

    f.open(Folder.READ_ONLY);

    // we can continue operating on folder f
  • 哪种方法更好,将文件夹引用保存在以全名作为键的hastable中,还是每次都执行tempStore.getFolder(foldername)?例如我们必须处理INBOX,优先选择使用

IMAPFolder f = folderCache.get(“ INBOX”); //假设已经放在hashtable folderCache中

要么

IMAPFolder f = tempStore.getFolder(“ INBOX”);

我按需生成Store实例,然后关闭它们,以便不使用邮件服务器上的大量资源。但是重新打开文件夹而不手动关闭不是一个好方法,因为它使用的仍然是资源?或使用这种方式是可以接受的,因为mailserver可以在需要时将其关闭,而我们只需要检查是否

  • 如果该文件夹已经打开,请继续操作,
  • 如果文件夹已关闭,请先执行打开操作,然后再操作,保持打开状态以备将来使用?

问题答案:

一个帖子的问题太多了。让我尝试回答其中的一些…

关闭文件夹后,您不应使用该文件夹中的任何消息对象,因此仅在使用完其消息后才关闭该文件夹。

如果单个用户有400个文件夹,则可以使用一个存储连接,因为每个打开的文件夹都会获得自己的连接。

如果您经常打开和关闭文件夹,则增加连接池大小会有所帮助,因为已关闭文件夹的连接将添加到池中,并且在您打开新文件夹时可以重新使用,而无需创建新连接。

关闭商店将关闭该商店的所有文件夹,但是如果涉及多个线程,则存在一个固有的竞争条件。关闭存储区是一种在使用完毕后清理所有连接的方法,而不是阻止其他线程重新打开文件夹的方法。

与每次调用getFolder相比,为关闭的文件夹缓存Folder对象不太可能具有很大的优势。



 类似资料:
  • 有没有办法连接到ms Exchange邮件服务器中的IMAP文件夹,通过该文件夹我可以访问邮箱内的所有邮件。我的意思是所有邮件,包括收件箱,已发送邮件和其他与收件箱文件夹处于同一层次结构中的文件夹。 我在gmail IMAP中寻找类似于[Gmail]/All Mail文件夹的东西。这个文件夹让我可以一次访问所有文件夹中的所有邮件。

  • 问题内容: 我正在尝试阅读我的消息,我可以获取它来打印标题,但发件人和内容显示得很滑稽。这是我用来显示消息的代码: 输出如下: 为什么不打印出from语句的实际电子邮件地址?为什么不打印出实际的身体内容?(我只是在纯文本中很有趣。) 整个代码: 谢谢! 问题答案: 对于纯文本和html消息: 对于分段消息:

  • 我已经通过IMAP(outlook.office365.com)连接到一个电子邮件商店。我可以使用LIST命令确定哪些文件夹用于删除、垃圾邮件、发件箱等,该命令会传回我可以使用的标志。 问题是,“我怎么知道收件箱用什么?”。我可以硬编码这个名字,但似乎很快就会失败。我确信我遗漏了一些东西,因为如果其他文件夹被标记,那么“收件箱”将是一个奇怪的遗漏。 期待你的帮助。谢谢 PS-如果这对响应有影响,我

  • 我使用JavaMail和协议imap来组织电子邮件(gmail)。我创建了一个文件夹FOLDER1,代码如下: 我用代码移动消息: 它的工作原理 但我不明白。。。如果我想再次阅读邮件,但不想阅读已阅读的邮件,也不想阅读已创建文件夹中的邮件,则无法再次阅读。该名称已在收件箱中 有什么问题吗? 谢谢你的帮助

  • 我试图使用JavaMail1.4 API阅读电子邮件帐户Office365文件夹中的电子邮件。

  • 能更改XP文件夹和驱动器的图标,背景提示文字等的小工具。 用NSIS编写,附源代码: ;NSIS脚本 ;文件夹个性化 ;编写:ansifa ;E-mail: ansifa@163.com ;__________________________________ SetCompressor /SOLID /FINAL lzma XPStyle on CRCCHECK OFF !include "MU