2017-03-09 56 views
0

我正在阅读Office 365 Mail帐户的收件箱并下载它的附件(txt文件)。它适用于小于2 MB的小文件,但当我尝试使用20 MB文件时,它确实很慢。我在两台不同的机器(Linux和Windows)上测试代码,速度相同,速度非常慢。Java Mail慢速下载附件Office 365

String user = "[email protected]"; 
String password = "mypassword"; 
try{ 

    boolean foundSites = false; 

    // Get a Properties object 
    Properties properties = new Properties(); 

    properties.put("mail.imaps.host", host); 
    properties.put("mail.imaps.port", port); 
    properties.put("mail.imaps.starttls.enable", SSL); 
    //properties.put("mail.imap.fetchsize", "1000000"); 
    Session emailSession = Session.getDefaultInstance(properties); 

    //create the POP3 store object and connect with the pop server 
    Store store = emailSession.getStore("imaps"); 
    store.connect(host, user, password); 

    //create the folder object and open it 
    Folder emailFolder = store.getFolder("INBOX"); 
    emailFolder.open(Folder.READ_ONLY); 

    // retrieve the messages from the folder in an array and print it 
    Message[] messages = emailFolder.getMessages(); 
    System.out.println("messages.length---" + messages.length); 

    LocalDateTime now = LocalDateTime.now(); 
    int year = now.getYear(); 
    int month = now.getMonthValue(); 
    int day = now.getDayOfMonth(); 

    for (int i = messages.length - 1; i >= 0; i--) { 
    Message message = messages[i]; 


    Calendar cal = Calendar.getInstance(); 
    cal.setTime(message.getReceivedDate()); 
    int yearMessage = cal.get(Calendar.YEAR); 
    int monthMessage = cal.get(Calendar.MONTH) + 1; 
    int dayMessage = cal.get(Calendar.DAY_OF_MONTH); 



    if(year == yearMessage && month == monthMessage && day == dayMessage) 
    { 
     //The real code is doing this with 20 Subjects (20 emails) 
     if(message.getSubject().equalsIgnoreCase("Integration - Site Info") && foundSites != true) 
     { 
      System.out.println("found Integration - Site Info"); 

      Multipart multipart = (Multipart) message.getContent(); 
      List<File> attachments = new ArrayList<>(); 
      for (int j = 0; j < multipart.getCount(); j++) { 
       BodyPart bodyPart = multipart.getBodyPart(j); 
       if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) 
       { 
        InputStream is = bodyPart.getInputStream(); 
        File f = new File("./attachments/" 
          + "sites_"+Integer.toString(day)+"-"+Integer.toString(month)+"-"+Integer.toString(year)+".csv"); 
        FileOutputStream fos = new FileOutputStream(f); 
        byte[] buf = new byte[4096]; 
        int bytesRead; 
        while((bytesRead = is.read(buf))!=-1) { 
         fos.write(buf, 0, bytesRead); 
        } 
        fos.close(); 
        attachments.add(f); 
        foundSites = true; 
        break; 
       } 


      } 
     } 
    } 

    if(foundSites) 
    { 
     break; 
    } 
} catch (Exception e) { 
    System.out.println(e); 
} 

我可以创建线程,但有没有其他的选择?

只是旁注: 我用python试试代码,速度显着提高。

====================================== UPDATE 1:

我做了saveFile方法的改变,代码简化了很多,但仍然有相同的下载速度,每秒10 KB。

MimeBodyPart bodyPart = (MimeBodyPart) multipart.getBodyPart(j); 
if(Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) 
{ 
    bodyPart.saveFile("./attachments/" 
     + "sites_"+Integer.toString(day)+"-"+Integer.toString(month)+"-"+Integer.toString(year)+".csv"); 

我也用探查,结果是: enter image description here

enter image description here

+0

速度真的很慢吗?速度有多快? – shmosel

+0

你是否分析了代码?用jvisualvm运行它,并告诉我们哪个部分很慢。关闭我的头顶,你*可能*添加缓冲到'FileOutputStream'。 –

回答

1

修复这些common mistakes

使用MimeBodyPart.saveFile来简化您的代码以保存附件。

由于您使用的是“imaps”协议而不是“imap”协议,因此请将mail.imaps.fetchsize属性设置为足够大以获得所需性能,而不使用比要使用的内存更多的内存。或者如果你不关心你使用了多少内存,并且你确定自己总是有足够的空间,那么将mail.imaps.partialfetch设置为false。

+0

我做了saveFile方法,它真的简化了代码,但下载速度仍然在10 KB每秒。 –

+0

为什么不尝试我建议的其他更改? –

+0

我将'mail.imaps.partialfetch'属性设置为false,将'mail.imaps.fetchsize'设置为2000000 现在速度真的提高了!谢谢!你有关于如何优化计算这个值的一些建议? –