简体   繁体   中英

Using Javamail to get attachments

Good Morning,

I have been working on this project for a few days now and have ground to a halt. Downloading attachments seems to take forever and it would appear to be at the writing file to disk line. I have read about many options (FileChannel, bulk getContent and a few others but can not make this code execute at a reasonable rate) I am not to sure if the only bottle neck is the downloading of the files from O365 however I thought I would ask a question to see if somebody could review this code and hopefully tell me what I have done wrong. The goal of the application is to log into Exchange Online (o365) and download all attachments within a certain mail box. Please note that this code has been modified so many times to see if I could make performance increases by using threading and so on:

As I said I have shifted everything around a lot to try and make this work better so please don't blow me up for some of the code not making too much sense. I am not trying to get somebody else to finish this project, I am looking for guidance with a language that I do not have a great deal of experience with.

    package o365connect;

import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeBodyPart;

/**
 *
 * @author Charlie
 */
public class AttDownload extends Thread {
        public static int Lower = 0;
        public static int Upper = 0;
        public static int Counter = 0;
        public static Session session;
        public static Store store;
        public static Properties props = new Properties();
        public static boolean fTest = false;
    AttDownload(int i, int ii) {
        Lower = i;
        Upper = ii;
    }
    AttDownload() throws UnknownHostException {
        super();
    }
    @Override
    public void run() {
        String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
        String pop3Host = "outlook.office365.com";
        String mailStoreType = "imap";
        String path = "Inbox/Scans to file";
        String userName = "XXX@XXX.com";
        String password = "XXXXXXX";
        Folder emailFolder;
        try {
            props.setProperty("mail.imaps.socketFactory.class", SSL_FACTORY);
            props.setProperty("mail.imaps.socketFactory.fallback", "false");
            props.setProperty("mail.imaps.port", "993");
            props.setProperty("mail.imaps.socketFactory.port", "993");
            props.put("mail.imaps.host", "outlook.office365.com");
            session = Session.getInstance(props);
            int Size = functions.MBSize(pop3Host, userName, password, path);
            System.out.println(Size);
            store = session.getStore("imaps");
            store.connect(pop3Host, userName, password);
            emailFolder = store.getFolder(path);
            emailFolder.open(Folder.READ_ONLY);
            try {
                Message[] messages;
                messages = emailFolder.getMessages(Lower, Upper);
                System.out.println("starting thread for - " + Lower + " - " + Upper);
                int ASuc = receiveEmail(messages);
            } catch (MessagingException | IOException ex) {
                Logger.getLogger(AttDownload.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (NoSuchProviderException ex) {
            Logger.getLogger(AttDownload.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MessagingException ex) {
            Logger.getLogger(AttDownload.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public static int receiveEmail(Message messagesarr[]) throws IOException, MessagingException {
            for (Message messagesarr1 : messagesarr) {
                try {
                    Message message = messagesarr1;
                    Object content = message.getContent();
                    if (content instanceof String) {
                    } else if (content instanceof Multipart) {
                        Multipart multipart = (Multipart) message.getContent();
                        for (int k = 0; k < multipart.getCount(); k++) {
                            MimeBodyPart bodyPart = (MimeBodyPart) multipart.getBodyPart(k);
                            if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
                                long startTime = System.currentTimeMillis();
                                int ran = (int) startTime;
                                String fileName;
                                String fName = bodyPart.getFileName();
                                if (fName != null && !fName.isEmpty()) {
                                    fileName = fName.replaceAll("\\s+", "");
                                } else {
                                    continue;
                                }
                                if ("ATT00001.txt".equals(fileName)) {
                                    continue;
                                } else {
                                    System.out.println("starting copy of - " + fileName);
                                }
                                String destFilePath = "D:/Scans/";
                                bodyPart.saveFile(destFilePath + bodyPart.getFileName());
                                long stopTime = System.currentTimeMillis();
                                System.out.println("finished copying of - " + fileName + "  -  " + (stopTime - startTime) + " miliseconds.");
                                System.out.println(Counter);
                                Counter++;
                            } else {
                            }
                        }

                    }
                }catch (MessagingException e) {
                    System.out.println(e);
                }
            }
        return 1;
    }
}

Functions.java

package o365connect;

import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import static o365connect.AttDownload.store;

/**
 *
 * @author Oliver
 */
public class functions {

    public static int TestUser(String pop3host, String Username, String Password) throws NoSuchProviderException, MessagingException {
        try {
            Session session = Session.getInstance(AttDownload.props);
            store = session.getStore("imaps");
            store.connect(pop3host, Username, Password);
            return 0;
        } catch (MessagingException e) {
            System.out.println(e + "User Name Invalid");
            return 1;
        }
    }

    public static Folder TestFolder(Store store, String Path) throws MessagingException {
        Folder emailFolder;
        emailFolder = store.getFolder(Path);
        emailFolder.open(Folder.READ_ONLY);
        AttDownload.fTest = true;
        emailFolder.close(false);
        return emailFolder;
    }

    public static int MBSize(String pop3Host, String userName, String password, String Path) {
        int Size = 0;
        Session session = Session.getInstance(AttDownload.props);
        try {
            Store store = session.getStore("imaps");
            store.connect(pop3Host, userName, password);
            Folder emailFolder = store.getFolder(Path);
            emailFolder.open(Folder.READ_ONLY);
            Size = emailFolder.getMessageCount();
            emailFolder.close(false);
            store.close();
            return Size;
        } catch (MessagingException e) {
            System.out.println(e + "MBSize");
        }
        return Size;
    }
}

O365Connect.java

package o365connect;

import java.io.IOException;
import javax.mail.MessagingException;

public class O365Connect {



    public static void main(String[] args) throws IOException, MessagingException, InterruptedException {
        MainScreen ms = new MainScreen();
        ms.setVisible(true);
        AttDownload dl = new AttDownload(1, 1000);
       dl.start();

    }
}

Edit:

props.put("mail.imaps.fetchsize", "819200");
props.put("mail.imaps.partialfetch", "false");

sped things up, 128 seconds down to 12 seconds to download a 7mb file.

fetchsize is not used if partialfetch is false; it will download the entire attachment in one request. As long as you have enough memory for the largest possible attachment, that's fine. Otherwise, leave partialfetch set to true (default) and set the fetchsize large enough to give reasonable performance without using excessive memory.

JavaMail properties are described in the javadocs, on the page for each protocol provider. For example, the IMAP provider properties are described on the com.sun.mail.imap package javadoc page .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM