2012-01-19 111 views
4

我正在使用JavaMail API創建電子郵件客戶端。一切工作正常,如我能夠連接到郵件服務器(使用IMAP),刪除郵件,檢索收到的郵件,並顯示給用戶等。無法使用JavaMail下載Java附件的PDF附件

現在問題來了,當下載「PDF附件」。 PDF文件沒有完全下載...它缺少一些包含。

如果某些PDF附件的大小爲38 Kb,當我使用IE或任何其他Web瀏覽器下載附件時,但是使用我的java代碼下載時,它的大小爲37.3 Kb。它是不完整的 因此,當我嘗試使用Adobe Reader時它顯示錯誤消息,打開它的「文件已損壞......」

這是我寫下載附件代碼:

public boolean saveFile(String filename,Part part) throws IOException, MessagingException { 
    boolean ren = true; 
    FileOutputStream fos = null; 
    BufferedInputStream fin = null; 
    InputStream input = part.getInputStream(); 

    File pdffile = new File("d:/"+filename); 
    try{ 
     if(!pdffile.exists()){ 
      fos = new FileOutputStream(pdffile); 
      fin = new BufferedInputStream(input); 
      int size = 512; 
      byte[] buf = new byte[size]; 
      int len; 

      while ((len = fin.read(buf)) != -1) { 
       fos.write(buf, 0, len); 
      } 

      input.close(); 
      fos.close(); 
     }else{ 
      System.out.println("File already exists"); 
     } 
    }catch(Exception e){ 
     ren = false; 
    } 
    return ren; 
} 

上午我錯過了什麼?任何有用的幫助表示讚賞。

+0

如果使用會發生什麼[MimeBodyPart的#saveFile的(文件)](http://javamail.kenai.com/nonav/ javadocs/javax/mail/internet/MimeBodyPart.html#saveFile(java.io.File))或採用字符串的等效方法?如果失敗了,我會嘗試聯繫Bill Shannon(JavaMail開發人員,他經常訪問[forums.oracle.com上的JavaMail論壇](https://forums.oracle.com/forums/forum.jspa?forumID=975) )。 –

+0

BTW:指定你正在使用的JavaMail版本也是有幫助的,我記得如果BASE64編碼對在緩衝區的邊界上,對於一些較早的版本,解碼附件時有一些問題(跳過字節)。 –

+0

@MarkRotteveel是的,我已經使用MimeBodyPart的savefile(文件)方法,但它也失敗了,它的結果相同(在結束時跳過一些字節),我正在使用JavaMail 1.4.4。謝謝.. – Shantanu

回答

1

終於讓我找到解決方案在JavaMail FAQ閱讀郵件,IMAP部分 Gmail的服務器正在運行的錯誤帶附件

首先,我試圖設置partialfetch屬性假,但有時它的作品有時沒有

props.setProperty("mail.imap.partialfetch", "false"); 

FAQ中列舉了另一種方法,它只是使用MimeMessage的複製構造函數,並在某些tempmsg中存儲orignal對象,然後獲取tempmsg的內容

MimeMessage tempmsg = new MimeMessage(msg); 
    Multipart part = (Multipart) tempmsg.getContent(); 

,現在執行它應該工作的所有操作..

有關實際發生的事情轉到JavaMail FAQ閱讀郵件,IMAP部分,你會找到所有的答案的詳細信息...

+0

對不起,但我無法重現您的解決方案。第一行MimeMessage tempmsg = new MimeMessage(msg);不爲我編譯:無法解析構造函數'MimeMessage(javax.mail.Message)'。我究竟做錯了什麼?你傳遞給構造函數的是什麼類型的對象? – achecopar

4

花了幾個小時就這個問題和最後弄清楚了。

props.setProperty("mail.imaps.partialfetch", "false"); 

爲我做了。上面幾乎同樣的事情@Shantanu,而是因爲我是用

store = session.getStore("imaps"); 

我需要使用「IMAP 小號」爲partialfetch爲好。

工程就像一個魅力。

全部下面的代碼:

// Load mail properties 
Properties mailProperties = System.getProperties(); 
mailProperties.put("mail.mime.base64.ignoreerrors", "true"); 
mailProperties.put("mail.imaps.partialfetch", "false"); 

// Connect to Gmail 
Session session = Session.getInstance(mailProperties, null); 
store = session.getStore("imaps"); 
store.connect("imap.gmail.com", -1, "username", "password"); 

// Access label folder 
Folder defaultFolder = store.getDefaultFolder(); 
Folder labelFolder = defaultFolder.getFolder("mylabel"); 
labelFolder.open(Folder.READ_WRITE); 

Message[] messages = labelFolder.getMessages(); 

saveAttachments(messages); 

...

private void saveAttachments(Message[] messages) throws Exception { 

for (Message msg : messages) { 


    if (msg.getContent() instanceof Multipart) { 
     Multipart multipart = (Multipart) msg.getContent(); 

     for (int i = 0; i < multipart.getCount(); i++) { 
     Part part = multipart.getBodyPart(i); 
    String disposition = part.getDisposition(); 

    if ((disposition != null) && 
     ((disposition.equalsIgnoreCase(Part.ATTACHMENT) || 
     (disposition.equalsIgnoreCase(Part.INLINE))))) { 
     MimeBodyPart mimeBodyPart = (MimeBodyPart) part; 
     String fileName = mimeBodyPart.getFileName(); 

     File fileToSave = new File(fileName); 
     mimeBodyPart.saveFile(fileToSave); 
    } 
     } 
     } 
    } 
} 
+0

我得到空附件,'prop.setProperty(「mail.imaps.partialfetch」,「false」)'也幫助了我。 – Anton