Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  13:16[Войти] | [Зарегистрироваться]
Ответ на вопрос № 83633

08-02-2019 04:59
Доброго времени суток!

Возникла задача работать с Ini файлами в Unicode
Использую TMemIniFile
В результате, если файл в кодировке UTF8 (кодовая страница 65001), то не считывает ничего.
Если копаться в исходниках, то функция из модуля SysUtils

function TMBCSEncoding.GetCharCount(Bytes: PByte; ByteCount: Integer): Integer;
begin
  Result := UnicodeFromLocaleChars(FCodePage, FMBToWCharFlags,
    PAnsiChar(Bytes), ByteCount, nil, 0);
end;


Возвращает 0. Ну и дальше понятно, что ничего никуда не загружается.
Использую так:

TranslatedMemIni := TMemIniFile.Create(TranslationFile, TEncoding.UTF8);


Непосредственно в сам Ini файл с помощью Notepad++ добавил несколько специфичных символов с умляутами (всякие галочки над буквами), чтобы сразу посмотреть результат.
Но, как уже сказал, вообще ничего не считалось. Пробовал в разных вариантах. Читает только в TEncoding.ASCII, TEncoding.Default, TEncoding.UTF7. В остальных нет.
Если делаю так:

TranslatedMemIni := TMemIniFile.Create(TranslationFile, TEncoding.Default);


все считывается, но специфичные символы превращаются в аброкадабру. (например pЕ™Г­zemГ­ вместо prizemi). Вся остальная латиница читается правильно.

Вопрос: как правильно прочитать (а потом и записать) в кодировке UTF8.

P.S.
Win 7 x64
Delphi XE

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

18-02-2019 09:48 | Комментарий к предыдущим ответам
Странно, не знал, что проблемы с INI файлом могут быть. Проверено, что обычный INI файл (правда, в Lazarus) без проблем цепляет UTF-8 кодированные значения в INI файлах, проблем вообще никаких. Правда, имена ключей и секций у меня были только англоязычными, возможно, из-за этого всё работало. Но значения по меньшей мере были на английском, русском и французском (другие нафиг не надо было).

10-02-2019 14:00 | Сообщение от автора вопроса
Забыл написать, что это все уже было на Delphi 10.1 Berlin
Но для XE тоже работает.

10-02-2019 13:54 | Сообщение от автора вопроса
Спасибо.

Задумка как раз и состояла в том, что тексты должны читать другие люди и даже на тех языках, в которых я вообще ничего понять не смогу :-)

Странно, но облазив весь интернет я не нашел решения этого вопроса.
И чтобы помочь другим приведу вариант решения, который заработал у меня.
Совсем не оптимальный, но другого не нашел, а время поджимает чтобы продолжать искать просто лучшие пути уже решенной задачи.

Загружаю Ini файл в TMemoryStream
Затем копирую содержимое в буфер. Наверно можно было обойтись просто ссылкой на Ms.Memory, но так не пробовал.


  Ms := TMemoryStream.Create;
  Try
    Ms.LoadFromFile(TranslationFile);
    SetLength(Buf, Ms.Size);
    Ms.Read(Buf[0], Ms.Size);
    I := TEncoding.GetBufferEncoding(Buf, Encoding, TEncoding.UTF8);
    CodePage := Encoding.CodePage;
  finally
    FreeAndNil(Ms);
  end;


Цель этого действия определить кодировку.
Затем, танцы с бубном :) вокруг загрузки в TStringList
Если просто вызвать LoadFromFile, то теряются спецсимволы. (Может только в моей конфигурации?)
Но именно из-за этого делаю следующим образом
Считываю из файла в строку без преобразования кодировки
Затем присваиваю переменной String, что можно в принципе не делать (это мне так удобнее было для отладки)


RBS:RawByteString;
S:String;
.....
  AssignFile(Txt, TranslationFile);
  Reset(Txt);
  while Not Eof(Txt) do
  begin
    Readln(Txt, RBS);
    S := RBS;
    Fs.Add(S);
  end;
  closeFile(Txt);



Затем уже создаю TMemIniFile в памяти
и копирую ему считанный список строк


  TranslatedMemIni := TMemIniFile.Create('', TEncoding.UTF8);
  TranslatedMemIni.SetStrings(Fs);


После этого TranslatedMemIni содержит реальные данные Unicode и с ними можно работать обычным способом для Ini файлов.

Кстати, следующей проблемой была необходимость отобразить данные Unicode в CxGrid от DevExpress.
Опять же странно, но очень мало информации по данной теме находится в поиске Яндексом и то вся о том, что CxGrid не поддерживает Unicode и т.п.
Это чушь.
Использовал таблицу в памяти TdxMemData
и при создании полей для нее нужно просто выбрать тип не просто String, а WideString и все корректно отображается.
Сначала же, если тип поля объявлен просто String
присвоение значения методом FieldByName('Field').asString преобразовывало спецсимволы с умляутами
После того, как заменил на WideString - работает.

Это все для тех, кто будет искать подобные ответы.
P.S.
Если есть другие варианты решения данной проблемы или улучшения данного метода пишите сюда несмотря на давность этого сообщения.

10-02-2019 09:02
Чтобы не заморачиваться с перекодировками Unicod'а, каковые перекодировки зачастую
работают довольно задумчиво, можно написать свой собственный перекодировщик. Он будет
символы Unicode, которые не ASCII, перекодировать во что-то вроде %XXXX, где XXXX-четыре
шестнадцатеричные цифры. И, соответственно, обратно тоже. Если такой перекодировщик у вас
будет, то можно писать не только в ini-файл, а вообще во все "текстоподобное".
Сам я с такой проблемой сталкивался, писать надо было и в ini-файл, и в текстовый, много
куда. Если есть свой "личный" перекодировщик - никаких проблем. Если только не надо, чтобы
этот текст читал кто-то другой, вот тогда - не прокатит...
Код перекодировщика могу дать, не жалко... :-)

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
"Мы с тобой одной крови — ты и я!". Чьи это заветные слова?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования