用 Java 解码 Mail.app 电子邮件附件文件名

发布于 2024-11-02 11:18:49 字数 892 浏览 1 评论 0原文

我在解码电子邮件附件的文件名时遇到问题。目前我正在使用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 发送时有没有办法解码文件名?或者也许还有其他图书馆?

谢谢! 亚当

I've got a problem with decoding the filename of an e-mail attachment. Currently I'm using JavaMail 1.4.2. The file is named "Żółw.rtf" (that's polish for Turtle.rtf). The mail is sent using Mail.app (which seems to be quite significant). The important headers are:

--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

The corresponding javax.mail.Part.getFileName() returns "=?utf-8?Q?Z=CC=87o=CC=81=C5=82w=2Ertf?=", which, after applying MimeUtility.decodeText, is: "Żółw.rtf". Clearly not the original :).

For comparison, MimeUtility.encodeText returns:

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

in contrast to:

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

coming from the e-mail.

According to my research, the letter "Ż" can be encoded in two ways: either as a single letter or as "Z" + above-dot. MimeUtility.encodeText uses the former, Mail.app the latter.

However I want to be able to decode both. Is there a way to decode the filename when sent from Mail.app using JavaMail? Or maybe there is some other library?

Thanks!
Adam

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转身泪倾城 2024-11-09 11:18:49

结果你必须规范化字符串:

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

很奇怪,但是有效! :)
更详细地说,由于 Mail.app 将“Ż”编码为两个字符:“Z”+“上面的点”,因此必须使用规范化器重新组合。

亚当

Turns out you have to normalize the string:

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

Weird, but works! :)
In more details, as Mail.app encodes "Ż" as two characters: "Z" + "dot-above", this then has to be recombined using the Normalizer.

Adam

别挽留 2024-11-09 11:18:49

我不知道它是否有用我有一部分java编码,它检查邮件文件附件,如果存在,则将其保存在指定的文件路径中,并采用指定的名称和扩展名,如果文件名已存在于路径下,则它将值增加到文件名的末尾。这是代码片段:

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+"*******");
    }

希望您觉得

它有用。

问候,
拉吉夫

I dont know if it's useful I have a part of java coding which checks for mail file attachments and if present then save it in the specified filepath taking the name and extension specified and if the filename already exists under the path then it increments a value to the end of the filename. So here's the code snippet :

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+"*******");
    }

here

Hope you find it useful.

Regards,
Rajeev

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文