2017-03-09 110 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 現在速度真的提高了!謝謝!你有關於如何優化計算這個值的一些建議? –