【问题标题】:Decoding a Mail.app e-mail attachment filename in Java在 Java 中解码 Mail.app 电子邮件附件文件名
【发布时间】:2011-08-09 10:38:16
【问题描述】:

我在解码电子邮件附件的文件名时遇到问题。目前我正在使用 JavaMail 1.4.2。该文件名为“Żółw.rtf”(这是 Turtle.rtf 的波兰语)。邮件是使用 Mail.app 发送的(这似乎很重要)。重要的标题是:

--Apple-Mail-19-721116558
Content-Disposition: attachment;
   filename*=utf-8''Z%CC%87o%CC%81%C5%82w.rtf
Content-Type: text/rtf;
   x-unix-mode=0644;
   name="=?utf-8?Q?Z=CC=87o=CC=81=C5=82w=2Ertf?="
Content-Transfer-Encoding: 7bit

对应的javax.mail.Part.getFileName()返回“=?utf-8?Q?Z=CC=87o=CC=81=C5=82w=2Ertf?=”,其中,应用MimeUtility.decodeText后, 是:“ZÃáoÃÅ≈Çw.rtf”。显然不是原版:)。

为了比较,MimeUtility.encodeText 返回:

=?UTF-8?Q?=C5=BB=C3=B3=C5=82w.rtf?=

对比:

=?utf-8?Q?Z=CC=87o=CC=81=C5=82w=2Ertf?=

来自电子邮件。

根据我的研究,字母“Ż”可以通过两种方式编码:单个字母或“Z”+上点。 MimeUtility.encodeText 使用前者,Mail.app 使用后者。

但是我希望能够同时解码两者。有没有办法在使用 JavaMail 从 Mail.app 发送文件名时解码文件名?或者也许还有其他图书馆?

谢谢! 亚当

【问题讨论】:

  • 回答我自己,你必须规范化字符串: String decoded = MimeUtility.decodeText(part.getFileName());返回 Normalizer.normalize(解码,Normalizer.Form.NFC);奇怪,但有效! :)
  • 很高兴您找到了解决方案!您可以将其发布为答案吗?这将帮助将来遇到同样问题的人(你可能也会得到支持 ;-))

标签: java macos mime jakarta-mail


【解决方案1】:

原来你必须规范化字符串:

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

很奇怪,但有效! :) 更详细地说,由于 Mail.app 将“Ż”编码为两个字符:“Z”+“dot-above”,因此必须使用 Normalizer 重新组合。

亚当

【讨论】:

  • 10 年后,这仍然对我有很大帮助。我正在尝试制作一个程序,该程序可以下载电子邮件的附件。然而,有些附件是西里尔字母,有些是希腊字母。这保存了我的代码!非常感谢。
【解决方案2】:

我不知道它是否有用我有一部分 java 编码用于检查邮件文件附件,如果存在则将其保存在指定的文件路径中,并采用指定的名称和扩展名,如果文件名已经存在于路径下,那么它会递增文件名末尾的值。所以这里是代码 sn-p :

enter

Multipart mp = (Multipart)messages[i].getContent();

 for (int j=0, n=mp.getCount(); j<n; j++) {

     Part part = mp.getBodyPart(j);

       String disposition = part.getDisposition();

        if ((disposition != null) && 
                                  ((disposition.equals(Part.ATTACHMENT) || 
                                   (disposition.equals(Part.INLINE))))){                                      

       String path = "c:\\Temp;

                                    saveFile(part.getFileName(), part.getInputStream(),path);

       }
  }

  public static void saveFile(String filename,InputStream input, String path) throws IOException {
    if (filename == null) {
    filename = File.createTempFile("xx", ".out").getName();
    }

     try{
    boolean success = (new File(path)).mkdirs();
    if (success) {
      System.out.println("Directories: " + path + " created");
    }

    }catch (Exception e){//Catch exception if any
      System.err.println("Error: " + e.getMessage());
    }

    String filenamepath = path + "//"+filename;
    File file = new File(filenamepath);
    for (int i=0; file.exists(); i++) {     

         String fname="";
            String ext="";
            int mid= filenamepath.lastIndexOf(".");
            fname=filenamepath.substring(0,mid);
             ext=filenamepath.substring(mid+1,filenamepath.length());               


    file = new File(newpath);
    }
    FileOutputStream fos = new FileOutputStream(file);
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    BufferedInputStream bis = new BufferedInputStream(input);
    int aByte;
    while ((aByte = bis.read()) != -1) {
    bos.write(aByte);
    }
    bos.flush();
    bos.close();
    bis.close();
    System.out.println("File saved to :"+file+"*******");
    }

这里

希望你觉得它有用。

问候, 拉吉夫

【讨论】:

  • 谢谢,但问题在于 part.getFileName():这可能会返回例如=?utf-8?Q?Z=CC=87o=CC=81=C5=82w=2Ertf?=,如果文件名包含非ASCII字符。这必须被解码:)。
  • 0 否决票 嗨,不知道此链接是否为您提供任何线索。代码确实有正确解码文本的示例。根据他们的说法,在某些情况下 JavaMail 无法获取由一些不符合 mime 的邮件程序引起的多编码单词或损坏,并提供了解码此类文本的示例。 szszi.hu/~pts/oxinstall/… 我希望它对你有用。问候,拉吉夫
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
相关资源
最近更新 更多