Расшифровка имени файла вложения электронной почты Mail.app в Java - PullRequest
7 голосов
/ 20 апреля 2011

У меня проблема с расшифровкой имени файла вложения электронной почты. В настоящее время я использую 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 второе.

Однако я хочу иметь возможность декодировать оба. Есть ли способ декодировать имя файла при отправке из Mail.app с помощью JavaMail? Или, может быть, есть какая-то другая библиотека?

Спасибо! Адам

Ответы [ 2 ]

12 голосов
/ 22 апреля 2011

Оказывается, вам нужно нормализовать строку:

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

Странно, но работает!:) Более подробно, поскольку Mail.app кодирует «Ż» в виде двух символов: «Z» + «точка над», то его необходимо заново объединить с помощью нормализатора.

Адам

0 голосов
/ 20 апреля 2011

Я не знаю, полезно ли это, у меня есть часть кода Java, которая проверяет вложения почтовых файлов и, если присутствует, сохраняет ее в указанном пути к файлу с указанным именем и расширением, и если имя файла уже существует под путем, то оно увеличивается значение до конца имени файла. Итак, вот фрагмент кода:

enter

Multipart mp = (Multipart) сообщения [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+"*******");
    }

здесь

Надеюсь, вы найдете это полезным.

С уважением, Раджив

...