AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.02.2011, 11:17   #1  
Denicce is offline
Denicce
Участник
 
62 / 54 (2) ++++
Регистрация: 22.03.2005
Адрес: Москва
Lightbulb Открыть текстовый файл ansi (win1251) на нерусифицированной Windows.
Задача: прочитать в axapta текстовый файл, сохраненный в кодировке Windows-1251 (ansi) на нелокализованной Windows. Смена региональных настроек ОС недопустима. Версия axapta DAX40SP2.

В-общем, поискал, порылся, сделал следующим образом, может, что получше предложите. За реализацию WinApi функции преобразования текста ansi->utf8 спасибо AndyD.

Пробовал через Binary и получение массива символов через COMVariant и SafeArray. Потом в цикле сдвиг зоны кодов символов 192-255 ("А".."я") на 848 вперед. Работает, но медленно.

Может, как-то упростить и сделать через .NET (на форуме можно найти функции преобразования ansi->utf8, но, как я понял, там могу быть проблемы с подключением references у пользователей.

Не сообразил, как можно преобразовать строку и сразу с ней работать, без сохранения файла с конвертированным текстом и открытия оного как utf-8 через TextBuffer. Тут тоже какие-то оптимизации возможны, я думаю.

P.S.
Кстати, вся эта канитель возникла при импорте банковской выписки, сохраненной в формате 1С. Не нашли возможности формировать эту выписку сразу в Unicode, что исключило бы проблемы с чтением файла.

X++:
client static void kird_fileAnsi2utf8_forum(Args _args)
{
    TextBuffer          tb = new TextBuffer();
    FileName            filenameANSI = "c:\\TEMP\\ansi.txt";
    FileName            filenameUTF8 = "c:\\TEMP\\utf8.txt";
    str                 text;
    
#define.CP_WinCyrillic(1251) // windows cyrillic
#define.CP_UTF8(65001)       // UTF-8

str Ansi2Utf8(str Ansi) // THANKS AndyD
{
    DLL             _kernelDLL        = new DLL("KERNEL32");
    DLLFunction     MultiByteToWideChar  = new DLLFunction(_kernelDLL, "MultiByteToWideChar");
    DLLFunction     WideCharToMultiByte  = new DLLFunction(_kernelDLL, "WideCharToMultiByte");
    Binary          buf, buf1;
    int             len;
    str             res;
    ;
    res = "";
    if (Ansi)
    {
        buf = new Binary(strlen(Ansi)+1); // тут нужно +1, иначе код сваливается с ошибкой.
        buf.string(0, Ansi);
        buf1 = new Binary((strlen(Ansi) + 1) * 2);
        MultiByteToWideChar.returns(ExtTypes::DWord);
        MultiByteToWideChar.arg(ExtTypes::DWord, ExtTypes::DWord, ExtTypes::Pointer, ExtTypes::DWord,
                                ExtTypes::Pointer, ExtTypes::DWord);
        if (MultiByteToWideChar.call(#CP_WinCyrillic, 0, buf, strlen(Ansi) + 1, buf1, strlen(Ansi) + 1))
        {
            WideCharToMultiByte.returns(ExtTypes::DWord);
            WideCharToMultiByte.arg(ExtTypes::DWord, ExtTypes::DWord, ExtTypes::Pointer, ExtTypes::DWord,
                                    ExtTypes::Pointer, ExtTypes::DWord, ExtTypes::DWord, ExtTypes::DWord);
            len = WideCharToMultiByte.call(#CP_UTF8, 0, buf1, strlen(Ansi) + 1, buf, 0, 0, 0);
            if (len)
            {
                buf = new Binary(len);
                if (WideCharToMultiByte.call(#CP_UTF8, 0, buf1, strlen(Ansi) + 1, buf, len, 0, 0))
                    res = buf.string(0);
            }
        }
    }
    return res;
}

void saveIO() // сохраняем через AsciiIo, т.к. работает быстрее в 5-10 раз, чем сохранение через TextBuffer.toFile()
{
    AsciiIo aSCIIFile;
    ;
    aSCIIFile = new AsciiIo(filenameUTF8, "w"); 
    aSCIIFile.write(text); 
    return;
}
    ;

// OPEN FILE
    tb = new TextBuffer(); 
    if (! tb.fromFile(filenameANSI)) 
        throw error('bad open ansi'); 
    text = tb.getText();
    info(strfmt("ansi: %1", text));

// CONVERT TEXT
    text =  num2char(0xEF)+num2char(0xBB)+num2char(0xBF)+ // utf-8 file header. it is needed.
            Ansi2Utf8(text);

// SAVE FILE IN UTF-8
    saveIO();

// OPEN FILE AS UTF-8
    tb = new TextBuffer(); 
    tb.fromFile(filenameUTF8, FileEncoding::UTF8); 
    text = tb.getText();
    info(strfmt("utf8: %1", text));
}
За это сообщение автора поблагодарили: Vasil (1).
Теги
ansi, text, textbuffer, textio, unicode, кодовая страница, текстовый файл, asciio

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как открыть файл novic DAX: Программирование 4 02.04.2010 11:18
Web-портал: открыть файл cherv DAX: Программирование 4 19.05.2008 16:42
Client Axapta 3.0 SP4 и Linux. Как запустить? Daiver DAX: Администрирование 10 28.06.2007 15:59
Экспорт в текстовый файл с разделителями EAlex DAX: Программирование 7 14.07.2004 15:17
Экспорт накладных в текстовый файл SNG DAX: Программирование 20 13.11.2003 16:31

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 00:29.