如何从imap只下载新的电子邮件?

时间:2011-01-18 14:14:51

标签: java imap javamail

我有一个用于使用imap存档电子邮件的应用程序。此应用程序中还有许多需要存档的imap帐户。

此时应用程序会不时连接到imap帐户并仅下载新电子邮件。我的问题是,每次连接到imap帐户时,它都会验证来自所有文件夹的所有电子邮件,并且只下载尚未下载的电子邮件(我存储所有电子邮件的Message-ID,只下载具有Message-ID的电子邮件)没有存储)。 所以我想知道是否有替代方案,因为需要一些时间来验证所有电子邮件(10-20K需要2-5分钟)。

我使用JavaMail API连接到imap帐户。

4 个答案:

答案 0 :(得分:6)

javadoc有帮助:

IMAPFolder提供方法:

getMessagesByUID(长开头,长尾)和

getUID(消息消息)

使用getUID(),您可以获取已下载的最后一条消息的UID。使用getMessagesByUID,您可以将已下载的最后一条消息定义为start-range,并使用方法getUIDNext()查找最后一条消息,该消息将作为范围的结尾。

答案 1 :(得分:3)

只检查标题,当你到达已知的(最后一个已知的)时,纾困:

例如

(我今天感觉特别好),这是一个除了真正的生产代码(一些部分被剪切,所以它可能无法编译,state.processed是一些优先设置LinkedHashMap代理[keySet()](和w / some max boundary boolean removeEldestEntry())

 try {
      store = mailSession.getStore("imap");
      try {
        store.connect();
        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_ONLY);

        int count = folder.getMessageCount();
        for(int localProc=0, chunk=49;localProc<10 && count>0; count -=chunk+1){


          Message messages[] = folder.getMessages(Math.max(count-chunk, 1), count);

          FetchProfile fp = new FetchProfile();
          fp.add(FetchProfile.Item.ENVELOPE);
          fp.add("Message-ID");
//add more headers, if need be
          folder.fetch(messages,fp);

          for (int i=messages.length;--i>=0;) {

            //can check abort request here
            Message  message = messages[i];


            String msgId = getHeader(message,"Message-ID");
            if (msgId!=null && !state.processed.add(msgId)){            
              if (++localProc>=10){
                break;
              }
              continue;
            }
///process here, catch exception, etc..
          }
        }

        folder.close(false);        
      } catch (MessagingException e) {
        logger.log(Level.SEVERE, "Mail messaging exception", e);
      }
    } catch (NoSuchProviderException e) {
      logger.log(Level.SEVERE, "No mail provider", e);
    }

    if(store != null) {
      try {
        store.close();
      } catch (MessagingException e) {}
    }

答案 2 :(得分:1)

过滤SEEN标志。此标志用于查找新消息。一个警告是,如果您的用户使用多个阅读器,那么可能已经看到使用另一个阅读器。

答案 3 :(得分:0)

message-Id作为标题的一部分始终是唯一的,即使你手动设置它。我已经用gamil和racksoace测试了它。