Перейти к содержанию
Fire Monkey от А до Я
  • 0

Как узнать, в какой кодировке файл?


rareMax

Вопрос

В папке есть множество текстовых файлов. Как правило файлы  в юникоде, но иногда встречаются и другие(на данный момент находил только GB2312 кодировку).
Открываю файлы так

  // FileSource.LoadFromFile(FileName, TEncoding.GetEncoding(936));
    FileSource.LoadFromFile(FileName,TEncoding.UTF8); 

 
Как следствие, при открытии файла вылетает эксепшен, что не подходит кодировка. Знаю как можно открыть этот файл - закоментированый текст в коде выше. Вся сложность в том, как автоматически подобрать нужный класс TEncoding. Надеюсь на вашу помощь. 

Изменено пользователем Сысоев Максим
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

В общем случае - никак. Если файл не содержит преамбулу (1-3 байта) - идентификатор кодировки, то предстоит только догадываться. Если содержит - посмотрите исходники TStringList или TFile.AppendAllText.

Вкратце - для автоматического "угадывания" используемой кодировки задействуется TEncoding.GetBufferEncoding

Изменено пользователем kami
Ссылка на комментарий
  • 0
  • Модераторы

Вот такой код когда-то писал

var
  Stream: TBytesStream;
  Size: Integer;
  Buffer: TBytes;
  Encoding: TEncoding;
begin
  if OpenDialog1.Execute then
  begin
    Stream := TBytesStream.Create;
    try
      Stream.LoadFromFile(OpenDialog1.FileName);
      Buffer := Stream.Bytes;
      Size := TEncoding.GetBufferEncoding(Buffer, Encoding, TEncoding.Default);
    finally
      Freeandnil(Stream);
    end;

    if not TEncoding.IsStandardEncoding(Encoding) then
      Encoding := TEncoding.GetEncoding(Encoding.CodePage);

    ShowMessage(Encoding.EncodingName);
  end;

проблема в том что в недрах этой строчки

Size := TEncoding.GetBufferEncoding(Buffer, Encoding, TEncoding.Default);

всегда ворачивается Кодировка по умолчанию (Windows - ANSI, Остальные - UTF-8), если кодировка отличается от стандартных (ANSI, ASCII, UTF7, UTF8, Unicode, BigEndianUnicode)

 

И этот код никогда не выполнится

    if not TEncoding.IsStandardEncoding(Encoding) then
      Encoding := TEncoding.GetEncoding(Encoding.CodePage);

Вариант остается такой, собрать преамбулы всех кодировок и самому проверить их соответсвие :D

Ссылка на комментарий
  • 0

 

 

собрать преамбулы всех кодировок и самому проверить их соответсвие

Чем сейчас и занимаюсь - портирую код для опознования кодировки с с# :unsure:

Ссылка на комментарий
  • 0
if not TEncoding.IsStandardEncoding(Encoding) then
  Encoding := TEncoding.GetEncoding(Encoding.CodePage);

Абсолютно излишняя попытка действий. Более того, если бы код отработал, то вы получили бы утечку из-за утери первого Encoding.

 

 

 

 

 

собрать преамбулы всех кодировок и самому проверить их соответсвие

Чем сейчас и занимаюсь - портирую код для опознования кодировки с с# :unsure:

 

 

Имхо - работы много, а пользы будет мало. Файл не обязан содержать преамбулу. Совсем. Даже для well-known кодировок типа UTF8 преамбула является необязательной.

Ссылка на комментарий
  • 0

Я более подробно ознакомился с кодом - там идет аналитический метод. Запускал демку на шарпе - кодировку определяет правильно. Так что хоть работы будет много - польза тоже будет

Ссылка на комментарий
  • 0
  • Модераторы
if not TEncoding.IsStandardEncoding(Encoding) then
  Encoding := TEncoding.GetEncoding(Encoding.CodePage);
Абсолютно излишняя попытка действий. Более того, если бы код отработал, то вы получили бы утечку из-за утери первого Encoding.

Если читать внимательно, я объяснил что код не отработает. А это была иллюстрация как сделать кастомную кодировку зная CodePage
Ссылка на комментарий
  • 0
  • Модераторы

Я более подробно ознакомился с кодом - там идет аналитический метод. Запускал демку на шарпе - кодировку определяет правильно. Так что хоть работы будет много - польза тоже будет

Если получится не забудьте поделиться с сообществом

Ссылка на комментарий
  • 0

Если получится не забудьте поделиться с сообществом

Ну если получится - то думаю поделюсь. Впринипе уже почти все перевел на делфи. Но там нужно будет еще много деббажить. 

Ссылка на комментарий

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...