2011-10-16 71 views
2

我有使用Java郵件下載阿拉伯文附件文件的問題。使用JavaMail閱讀阿拉伯語附件

文件名總是不明確的。

問題是Bodypart將附件檢索爲非UTF-8字符。

private void getAttachments(Message temp) throws IOException, MessagingException { 
    List<File> attachments = new ArrayList<File>(); 

    Multipart multipart = (Multipart) temp.getContent(); 

    System.out.println(multipart.getCount()); 

    for (int i = 0; i < multipart.getCount(); i++) { 
     BodyPart bodyPart = multipart.getBodyPart(i); 
     if (!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) { 
      continue; // dealing with attachments only 
     } 
     InputStream is = bodyPart.getInputStream(); 

     // getFilename always have wrong characters set 
     byte [] fileBytes = bodyPart.getFileName().toString().getBytes(); 

     String filename = new String(fileBytes, "UTF-8");    

     File f = new File("C:\\Attachments\\" + filename); 

     System.out.println(f .getName()); 

     try { 
     if (f == null) { 
      //filename = File.createTempFile("VSX", ".out").getName(); 
      return; 
     } 

     FileOutputStream fos = new FileOutputStream(f); 
     BufferedOutputStream bos = new BufferedOutputStream(fos); 
     BufferedInputStream bis = new BufferedInputStream(is); 

     int aByte; 
     while ((aByte = bis.read()) >=0) { 
      bos.write(aByte); 
     } 

     fos.flush(); 
     bos.flush(); 
     bos.close(); 
     bis.close(); 
     fos.close(); 
    } // end of try() 
    catch (IOException exp) { 
     System.out.println("IOException:" + exp); 
    }   

     attachments.add(f); 
    } 
} 
+0

以何種方式是'用GetFileName()'給「錯」字? –

+0

@Donal Fellows: 文件名是احمدصالح。doc 調用字符串filename = bodyPart.getFileName(); filename =「=?WINDOWS-1256?B?483jzyDU5M/sLmRvYw ==?=」 –

回答

6

頭文件根據RFC 2047中描述的機制進行編碼(它是encoded-word)其中說段頭匹配=? <編碼>?B? <編碼字節>?=是一個字節編碼部分。該 <編碼>說如何解釋字節,(因爲它是B風格,而不是Q風格)的 <編碼字節>是base-64編碼。

這很複雜。幸運的是,您可以使用靜態的javax.mail.internet.MimeUtility.decodeText()方法輕鬆處理這個問題。這意味着你可以切換到這一點:

String filename = MimeUtility.decodeText(bodyPart.getFileName()); 

其實,你最好結合,與下一行也還有:

File f = new File("C:\\Attachments", 
        MimeUtility.decodeText(bodyPart.getFileName())); 

這是更好,因爲它避免了與建築的文件名不是更麻煩試圖全部手工完成。 (這也意味着,你可以分析出該文字路徑到一些配置的位置。)

3

這部分似乎打破對我說:

byte[] fileBytes = bodyPart.getFileName().toString().getBytes(); 
String filename = new String(fileBytes, "UTF-8");    

您使用的是默認的平臺編碼編碼的文件名(這你已經有了一個字符串)作爲字節,然後解碼他們使用UTF-8。

出了什麼問題:

String filename = bodyPart.getFileName(); 

?不要再做任何更多的編碼和解碼。當然,你的文件系統是否可以處理這樣的文件名是另一回事,但至少你現在不會丟失數據......

(你的方法複製文件數據也是如果出現異常情況,您可能會想要看Guava來編寫簡單的代碼,這樣就可以寫出......)

+0

文件名是احمدصالح。doc 致電 string filename = bodyPart.getFileName(); 文件名=「=?WINDOWS-1256?B?483jzyDU5M/sLmRvYw ==?=」 –

+1

@AhmedSaleh:好的,所以你需要一些能夠解碼的東西。調用'toString()'和'getBytes'不會對你有幫助。看看引用的可打印類 - 這基本上就是你在這裏得到的。你的JVM需要知道Windows-1256的代碼頁來成功解碼它。 –

+0

感謝您的回覆,但請告訴我什麼是可打印的類? –

2

嘗試:

String decoded = MimeUtility.decodeText(part.getFileName()); 
return Normalizer.normalize(decoded, Normalizer.Form.NFC);