2011-10-16 37 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);