使用JavaMail加速电子邮件检索

时间:2015-12-04 21:53:48

标签: java javamail imap fetch gmail-imap

目前我的代码使用IMAP(imaps)和JavaMail访问我的Gmail收件箱,目的是阅读从最新到最旧发送给自己的电子邮件,确定哪些邮件具有.zip或.xap格式的附件。如果找到,将显示电子邮件的主题,并询问我是否要下载附件。

如果我点击否,它会继续搜索。如果我单击是,它会调用createFolder方法来创建目录,将附件保存在那里,然后将其解压缩。

问题:我收件箱中的最新电子邮件有一个.zip文件,因此可以快速找到,但如果我点击“否”,则需要20秒才能找到包含zip / xap有两个原因:(1)最近有20多封电子邮件(2)最近有2封电子邮件包含附件但不是zip / xap。

我猜这是由于在识别其格式或其他冗余代码/方法之前发生隔离附件的递归所致?我已阅读获取配置文件可以提供帮助的herehere,而不是不必要地联系服务器。

我希望能大幅减少延迟。 Fetch / Envelope是否可行?我的代码是乱七八糟的,还是你可以分享一个示例解决方案?谢谢!

完整代码:

public class ReceiveMailImap {
    public ReceiveMailImap() {}

    public static void doit() throws MessagingException, IOException {
        Folder inbox = null;
        Store store = null;

        try {
            Properties props = System.getProperties();
            Session session = Session.getDefaultInstance(props, null);
            //session.setDebug(true);
            store = session.getStore("imaps");
            store.connect("imap.gmail.com", "myAccount@gmail.com", "myPassword");
            inbox = store.getFolder("Inbox");
            inbox.open(Folder.READ_WRITE);
            Message messages[] = inbox.getMessages();

            //  Loop newest to oldest
            for (int i = messages.length - 1; i >= 0; i--) {
                Message msg = messages[i];
                //If current msg has no attachment, skip.
                if (!hasAttachments(msg)) {
                    continue;
                }

                String from = "Sender Unknown";
                if (msg.getReplyTo().length >= 1) {
                    from = msg.getReplyTo()[0].toString();
                } else if (msg.getFrom().length >= 1) {
                    from = msg.getFrom()[0].toString();
                }
                subject = msg.getSubject();

                if (from.contains("myAccount@gmail.com")) {
                    //Get My Documents

                    subject = subject.replaceAll("[^a-zA-Z0-9.-]", "_");

                    //Call Save Attachment -->>
                    saveAttachment(msg.getContent());
                    msg.setFlag(Flags.Flag.SEEN, true);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (inbox != null) {
                inbox.close(true);
            }
            if (store != null) {
                store.close();
            }
        }
    }

    public static boolean hasAttachments(Message msg) throws MessagingException, IOException {
        if (msg.isMimeType("multipart/mixed")) {
            Multipart mp = (Multipart) msg.getContent();
            if (mp.getCount() > 1) return true;
        }
        return false;
    }

    public static void saveAttachment(Object content)
    throws IOException, MessagingException {
        OutputStream out = null;
        InputStream in = null;
        try {
            if (content instanceof Multipart) {
                Multipart multi = ((Multipart) content);
                int parts = multi.getCount();
                for (int j = 0; j < parts; ++j) {
                    MimeBodyPart part = (MimeBodyPart) multi.getBodyPart(j);
                    if (part.getContent() instanceof Multipart) {
                        // part-within-a-part, do some recursion...
                        saveAttachment(part.getContent());
                    } else {
                        int allow = 0;

                        if (part.isMimeType("application/x-silverlight-app")) {
                            extension = "xap";
                            allow = 1;
                        } else {
                            if (part.isMimeType("application/zip")) {
                                extension = "zip";
                                allow = 1;
                            }
                        }
                        if (allow == 1) {
                            int dialogResult = JOptionPane.showConfirmDialog(null, "The most recent file is: " + subject + " Would you like to download this file?", "Question", 0);
                            if (dialogResult == JOptionPane.YES_OPTION) {
                                savePath = createFolder(subject) + "\\" + subject + "." + extension;
                            } else {
                                continue;
                            }
                            out = new FileOutputStream(new File(savePath)); in = part.getInputStream();
                            int k;
                            while ((k = in .read()) != -1) {
                                out.write(k);
                            }

                            //Unzip
                            savePath = savePath.toString();
                            Unzip unzipFile = new Unzip();
                            unzipFile.UnZipper(dir, savePath);
                        } else {
                            continue;
                        }
                    }
                }
            }
        } finally {
            if ( in != null) { in .close();
            }
            if (out != null) {
                out.flush();
                out.close();
            }
        }
    }

    public static File createFolder(String subject) {
        JFileChooser fr = new JFileChooser();
        FileSystemView myDocs = fr.getFileSystemView();
        String myDocuments = myDocs.getDefaultDirectory().toString();
        dir = new File(myDocuments + "\\" + subject);
        savePathNoExtension = dir.toString();
        dir.mkdir();
        return dir;
    }

    public static void main(String args[]) throws Exception {
        ReceiveMailImap.doit();
    }
}

1 个答案:

答案 0 :(得分:2)

FetchProfile允许您“批量”预取一些消息信息。然后,当您访问Message对象的相应字段时,将使用此预取信息。您可能希望使用FetchProfile.Item.CONTENT_INFOFetchProfile.Item.ENVELOPE。除此之外,您的代码看起来很好。