Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Javamail API проблема с получением писем на русск.


Автор: firedrago 26.9.2005, 00:59
Всем привет,
вот столкнулся с новой проблемой.

переехал мой сервер с виндовса на линух и начал гробить все получаемые в кои или cp письма наповал.
стоит немецкий SUSE Linux.... явно что-то ему с кодировкой системы не нравится.... smile

Помогите кто знает.... smile

Код

    private void recieveMails(String serverAddr, String login, String password) throws MessagingException, IOException {
        Properties properties = System.getProperties();
        Session session = Session.getInstance(properties);
        Store store = session.getStore("pop3");
        store.connect(serverAddr, login, password);
        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        Message[] messages = folder.getMessages();
        saveMessages(messages);
        folder.close(true);
        store.close();
    }

    private void saveMessages(Message[] messages) throws IOException, MessagingException {
        if(messages != null){
            for(int i = 0; i < messages.length; i++) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                messages[i].writeTo(baos);
                
                try {
                    FileOutputStream fos = new FileOutputStream(Config.current().getSettings().getTmpPath() + File.separator + UniqueID.getUniqueID());
                    fos.write(baos.toByteArray());
                    fos.flush();
                    fos.close();
                    messages[i].setFlag(Flags.Flag.DELETED, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(messages.length == 0){
                System.out.println("No new Message...");                
            }else{
                System.out.println(messages.length + " new Messages...");
            }
        }
    }

Автор: chief39 26.9.2005, 10:44
Не совсем понятно, что значит "гробить" - скажи что конкретно получаешь на выходе smile

Попробуй так:

Код

FileOutputStream fos = new FileOutputStream("fff");
OutputStreamWriter owr = new OutputStreamWriter(fos, "cp1251");



Автор: firedrago 26.9.2005, 12:48
да там абра-кадабра из букв получается.....

что-то я торможу, пришли плс. полный пример как из ByteArrayOutputStream записать через OutputStreamWriter

Автор: firedrago 26.9.2005, 13:51
вроде сделал,
Код

    String file = "/tmp/000000000-"+ i + ".msg";
    FileOutputStream fos = new FileOutputStream(file);
    BufferedOutputStream ost = new BufferedOutputStream(fos);
    OutputStreamWriter owr = new OutputStreamWriter(ost, "cp1251");
    owr.write(baos.toString());
    owr.close();
    ost.close();
    fos.close();

делал с koi8, cp1251, utf-8 но после записи в файл заменяются все русские буквы на 3F

Автор: firedrago 26.9.2005, 14:24
нефига не понимаю..... javamail глючит или я......

если в коде
Код

private void saveMessages(Message[] messages) throws IOException, MessagingException {
        if(messages != null){
            for(int i = 0; i < messages.length; i++) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                messages[i].writeTo(baos);
                
                try {
                    FileOutputStream fos = new FileOutputStream(Config.current().getSettings().getTmpPath() + File.separator + UniqueID.getUniqueID());
                    fos.write(baos.toByteArray());
                    fos.flush();
                    fos.close();
                    messages[i].setFlag(Flags.Flag.DELETED, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(messages.length == 0){
                System.out.println("No new Message...");                
            }else{
                System.out.println(messages.length + " new Messages...");
            }
        }
    }


сделать System.out.println(messages[i].getContent()) то все ок,
а если messages[i].writeTo(System.out); то тут их уже убивает.... smile

Автор: firedrago 27.9.2005, 18:23
так что, никто не поможет ?! smile

Автор: LSD 28.9.2005, 16:14
Попробуй запустить установить на виндовой машине немецкую локаль и посмотреть появится ли ошибка, или на линуксе русскую.

Если не поможет, приведи рабочий пример, чтобы можно было запустить и проверить.

Автор: firedrago 28.9.2005, 21:17
у меня стоит немецкий виндовс - и все ок.
пример либо тут выложу, либо с поролями в PM

Автор: firedrago 28.9.2005, 21:57
@LSD логин и пароль в PM
Код


package test;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

public class TestEmailSave {

    private final static String host = "XXXXXXXXXXXXXXX";
    private final static String login = "XXXXXXXXX";
    private final static String passwd = "XXXXXXXX";
    
    public static void main(String[] args) {
        TestEmailSave es = new TestEmailSave();
        try {
            es.recieveMails(host, login, passwd);
        } catch (MessagingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    private void recieveMails(String serverAddr, String login, String password) throws MessagingException, IOException {
        Properties properties = System.getProperties();
        Session session = Session.getInstance(properties);
        Store store = session.getStore("pop3");
        store.connect(serverAddr, login, password);
        Folder folder = store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        Message[] messages = folder.getMessages();
        saveMessages(messages);
        folder.close(true);
        store.close();
    }

    private void saveMessages(Message[] messages) throws IOException, MessagingException {
        if(messages != null){
            for(int i = 0; i < messages.length; i++) {
                MimeMessage currMessage = (MimeMessage)messages[i]; // можно и не кастить на MimeMessage
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                currMessage.writeTo(baos);
                System.out.println(currMessage.getContent()); // вывод на консоль содержимого контента, на винде и на линухе все ок!
                currMessage.writeTo(System.out); // вывод на консоль, на линухе тут уже мертвый контент
                try {
                    System.out.println(MimeUtility.getDefaultJavaCharset());  // для теста, у меня на винде Cp1252 на линухе utf-8
                    
//                    так в оригинале :
                    String fileOrig = "c:\\000000000-"+ i + "-orig.msg";
                    FileOutputStream fos = new FileOutputStream(fileOrig);
                    fos.write(baos.toByteArray());
                    fos.flush();
                    fos.close();

//                    проба записи в других кодировках
                    String file = "c:\\000000000-"+ i + ".msg";
                    FileOutputStream fos1 = new FileOutputStream(file);
                    BufferedOutputStream ost = new BufferedOutputStream(fos1);
                    OutputStreamWriter owr = new OutputStreamWriter(ost, "UTF-8"); // пробовал Cp1252, koi8-r, utf-8 - все никак....
                    owr.write(baos.toString());
                    owr.close();
                    ost.close();
                    fos.close();
                
//                    messages[i].setFlag(Flags.Flag.DELETED, true); для теста не надо
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if(messages.length == 0){
                System.out.println("No new Message...");                
            }else{
                System.out.println("geted " + messages.length + " new Messages...");
            }
        }
    }

    
}


Автор: chief39 29.9.2005, 10:32
Мне кажется, дело именно в этом.
Цитата(LSD @ 28.9.2005, 16:14)
или на линуксе русскую.


Автор: firedrago 29.9.2005, 14:00
я вот что еще заметил,
если сделать
Код

System.out.println(MimeUtility.getEncoding(currMessage.getDataHandler()));

то под линухом выдает base64 а под виндой quoted-printable

может в этом проблема ?!
как эти установки изменить я не знаю... smile

Автор: LSD 29.9.2005, 22:20
Посмотрел я тест все работает так как и ожидалось.

Код
System.out.println(currMessage.getContent()); // вывод на консоль содержимого контента, на винде и на линухе все ок!

Выводит нормально.


Код
String fileOrig = "c:\\000000000-" + i + "-orig.msg";
FileOutputStream fos = new FileOutputStream(fileOrig);
fos.write(baos.toByteArray());
fos.flush();
fos.close();

записывает файл с письмом в правильной кодировке.


Код
String file = "c:\\000000000-" + i + ".msg";
FileOutputStream fos1 = new FileOutputStream(file);
BufferedOutputStream ost = new BufferedOutputStream(fos1);
OutputStreamWriter owr = new OutputStreamWriter(ost, "UTF-8"); // пробовал Cp1252, koi8-r, utf-8 - все никак....
owr.write(baos.toString());
owr.close();
ost.close();
fos.close();

записывает кракозябры (как и следовало ожидать ибо явно неправильно преобразовывается кодировка в baos.toString()).

А что у тебя не так?

Автор: firedrago 29.9.2005, 23:09
ты под виндой или под линухом пробовал ?

Автор: LSD 29.9.2005, 23:10
Цитата(firedrago @ 30.9.2005, 00:09)
ты под виндой или под линухом пробовал ?

Под виндой.

Автор: firedrago 30.9.2005, 14:25
smile все, вопрос решен!
большое спасибо @LSD, за то, что подтолкнул меня на правильную мысль!

дело окозалось совсем не в Javamail а в дальнейшем перемещении файла.

у меня было сделано так (см. moveFile()), что естественно не правильно и расходовало много памяти...:

Код

    public static void moveFile(String sourceFileName, String destFileName) throws FileNotFoundException, IOException {
        System.out.println("move " + sourceFileName + " to " + destFileName);
        writeFile(destFileName, readFile(sourceFileName));
        deleteFile(sourceFileName);
    }

    public static void writeFile(String fileName, String content) throws IOException {
        File f = new File(fileName);
        PrintWriter fout = new PrintWriter( new FileWriter( f ) );
        fout.print(content);
        fout.close();
    }

    public static String readFile(String fileName) throws IOException {
        FileReader fr = new FileReader(fileName);    
        BufferedReader br = new BufferedReader(fr); 
        StringBuffer msg = new StringBuffer();
        String record = null;  
        try {  
           while ( (record=br.readLine()) != null ) {
              msg.append(record + "\r\n"); 
           }  
    
        } catch (IOException e) {    
        }  
        fr.close();
        return msg.toString();
    }
    public static boolean deleteFile(String fileName) {
        File f = new File(fileName);
        boolean res = f.delete();
        return res;
    }


а решение, которое гораздо лучше и правильнее вот, может кому-то понадобится:

Код

    public static void moveFile(String sourceFileName, String destFileName) throws FileNotFoundException, IOException {
        FileChannel in = null, out = null;
        in = new FileInputStream(sourceFileName).getChannel();
        out = new FileOutputStream(destFileName).getChannel();
        in.transferTo( 0, in.size(), out);
        
         if (in != null)    in.close();
          if (out != null)    out.close();

        deleteFile(sourceFileName);
    }


всем спасибо за внимание!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)