Delphi как определить кодировку файла

Обновлено: 03.07.2024

Интернет ломает географические барьеры, обеспечивая возможность распространения программного обеспечения по всему миру. В результате приложения больше не могут использоваться в среде на основе одной только кодировки ANSI. В мире кодировка Unicode была воспринята как стандартное средство передачи текста и данных. Так как ею поддерживается фактически любая система письма в мире, текст в кодировке Unicode теперь является нормой в глобальном научно-техническом сообществе.

Что такое кодировка Unicode

Кодировка Unicode представляет собой схему кодировки символов, которая позволяет кодировать практически все алфавиты в виде одного набора символов. Кодировка Unicode позволяет компьютерам представлять текст для большинства систем письма в мире и обращаться с ним. Разработка кодировки Unicode поддерживается организацией Unicode Consortium и кодифицируется как стандарт. Проще говоря, кодировка Unicode представляет собой систему, позволяющую каждому использовать любые другие алфавиты. Представьте себе, существует даже версия Unicode клингонского языка.

Данная серия статей не предназначается для того, чтобы дать полное и точное изложение того, что представляет собой код Unicode и как он работает; ее предназначение - объяснить, как использовать кодировку Unicode в Delphi 2009. В данной статье, первой из трех, будет объяснено, почему так важна кодировка Unicode, и как в Delphi будет реализован новый тип строки UnicodeString.

Преимущества кодировки Unicode

Среди многих новых функциональных возможностей, которые можно обнаружить в Delphi 2009, имеется полная поддержка кодировки Unicode всем продуктом. Тип строки по умолчанию в Delphi - теперь строка в кодировке Unicode. Так как система Delphi в значительной степени построена на языке Delphi, интегрированная среда разработки, компилятор, библиотеки RTL и VCL - все они полностью поддерживают кодировку Unicode.

Переход на кодировку Unicode в Delphi вполне естественен. ОС Windows сама по себе полностью поддерживает кодировку Unicode, так что даже естественно, что приложениями, созданными для нее, строка Unicode используется как тип строки по умолчанию. И преимущества для разработчиков на Delphi не исчерпываются только возможностью использовать такой же тип строки, как и в Windows.

Добавление поддержки кодировки Unicode дает большие возможности разработчикам на Delphi. Разработчики на Delphi могут теперь считывать, записывать, принимать, создавать, отображать и обрабатывать данные в кодировке Unicode - и все эти возможности встроены прямо в продукт. Приложения, только с небольшими или, в некоторых случаях, нулевыми изменениями можно подготовить к поддержке любых данных самого разработчика, клиентов и пользователей. Приложения, возможности которых ранее ограничивались данными в кодировке ANSI, теперь можно легко приспособить для обработки почти любого набора символов в мире.

Разработчики на Delphi смогут теперь обслуживать глобальный рынок, разрабатывая свои приложения, даже если они не будут делать ничего специально для локализации или интернационализации своих приложений. ОС Windows сама по себе поддерживает много различных локализованных версий, и приложения Delphi должны иметь возможность адаптации и работы на компьютерах, на которых установлено большое число языковых настроек, поддерживаемых Windows, включая японскую, китайскую, греческую или русскую версии Windows. Пользователи программного обеспечения могут вводить в приложение текст или использовать имена путей не в кодировке ANSI. Приложения на основе кодировки ANSI в таких случаях не всегда работали бы так, как необходимо. Приложения Windows на основе Delphi с полной поддержкой Unicode смогут работать и в таких ситуациях. Даже если приложение не переведено на какие-либо другие разговорные языки, приложение, тем не менее, сохраняет нормальную работоспособность - независимо от языковой версии системы конечного пользователя.

Что касается существующих приложений Delphi на основе кодировки ANSI, то возможность локализации приложений и их распространения на рынке приложений с поддержкой Unicode в перспективе очень велика. И если необходимо локализовать приложения, среда Delphi позволяет сделать это очень просто, особенно непосредственно во время разработки. Интегрированная среда перевода (ITE) позволяет переводить, компилировать и развертывать приложение непосредственно в интегрированной среде разработки IDE. Если необходимы услуги по переводу извне, среда IDE позволяет экспортировать проект в такой форме, которая может использоваться переводчиками вместе с развертываемым приложением External Translation Manager (Диспетчер внешних переводов). Данный инструментарий работает вместе со средой Delphi IDE, и для среды Delphi, и для среды C++Builder, позволяя локализовать приложения при согласованном и простом управлении процессом.

Кодировка Unicode широко распространена в мире, и теперь разработчики на Delphi могут стать его частью естественным и органичным образом. Таким образом, если необходима возможность обработки данных в кодировке Unicode или есть стремление продавать приложения на растущих глобальных рынках, можно делать это с помощью Delphi 2009.

Немного о терминологии

Кодировка Unicode подразумевает использование некоторых новых терминов. Например, понятие "символ" в системе понятий Unicode менее точно, чем то, к которому, по-видимому, привыкли разработчики. Для кодировки Unicode более точным термином является "элемент кода". В Delphi 2009 размер SizeOf(Char) = 2, но даже и это не всегда. В зависимости от кодировки, это значение для данного символа может принимать значение больше двух байтов. Такие последовательности называются "суррогатными парами". Итак, элемент кода представляет собой уникальный код, назначенный элементу, определенному организацией Unicode Consortium (Unicode.org). Чаще всего это то же самое, что "символ", но не всегда.

Еще один термин, который относится к кодировке Unicode - маркер порядка байтов (BOM), и это очень короткий префикс, используемый в начале текстового файла, чтобы указать тип кодировки, используемый для данного текстового файла. Новый класс TEncoding (будет рассмотрен в части II) содержит метод класса GetPreamble, который возвращает маркер порядка байтов для заданной кодировки.

Теперь, после всех объяснений, рассмотрим, как в Delphi 2009 реализуется строка Unicode.

Новый тип UnicodeString

Тип строки по умолчанию в Delphi - новый тип UnicodeString. По умолчанию, тип UnicodeString имеет сходство с кодировкой UTF-16, той же самой, что используется в ОС Windows. В этом заключается отличие от предыдущей версии, в которой типом по умолчанию был тип AnsiString. Раньше в библиотеке Delphi RTL для обработки данных в формате Юникод использовался тип WideString, но этим типом, в отличие от типа AnsiString, не подсчитывалось количество ссылок, и поэтому он не являлся для разработчиков на Delphi строковым типом по умолчанию.

Для Delphi 2009 был разработан новый тип UnicodeString, который объединяет возможности типов AnsiString и WideString. Строка UnicodeString может содержать как символы Unicode, так и символы ANSI. (Необходимо заметить, что будут сохранены типы AnsiString и WideString.) Типы Char и PChar будут преобразованы соответственно в типы WideChar и PWideChar. Следует также заметить, что не были исключены никакие типы строк. По-прежнему сохраняются и доступны для использования все использовавшиеся разработчиками типы.

Однако в Delphi 2009 тип string по умолчанию эквивалентен типу UnicodeString. Кроме того, тип Char по умолчанию - тип WideChar, а тип PChar по умолчанию - PWideChar.

То есть для компилятора задается следующий код:

Присвоение типа UnicodeString совместимо со всеми другими типами строк, однако присвоения между AnsiStrings и UnicodeStrings будут вызывать соответствующие преобразования типов. Таким образом, присвоение типа UnicodeString типу AnsiString может привести к потере данных. То есть если строка UnicodeString содержит данные со старшими байтами, преобразование такой строки в строку AnsiString приведет к потере старших байтов данных.

Важно отметить, что новый тип UnicodeString имеет те же возможности, что и другие типы строк (за исключением, конечно, возможности содержать данные в кодировке Юникод). По-прежнему можно добавлять к ним любые строковые данные, индексировать их, объединять их знаком "+" и так далее.

Например, экземпляры строки UnicodeString все так же позволяют индексировать символы. Рассмотрим следующий код:

Переменная MyChar будет содержать символ, находящийся на первой позиции индекса, то есть "T". Функциональное содержание данного кода никак не изменилось. Аналогично, при обработке данных в кодировке Unicode:

Библиотека RTL содержит вспомогательные функции, которые позволяют пользователям выполнять явные преобразования кодовых страниц и размеров элементов. Если пользователь применяет функцию Move для массива символов, он не в состоянии учитывать размер элементов.

Как можно предположить, данный новый тип строки приводит к отличиям от существующего кода. В кодировке Unicode один символ больше не представляется одним байтом. Более того, один символ не всегда означает даже два байта. В результате, возможно, придется внести некоторые изменения в существующий код. Однако ведется очень серьезная работа над тем, чтобы упростить такой переход, и есть уверенность, что его можно осуществить и продолжить работу достаточно быстро. В частях II и III этой статьи будет продолжено обсуждение нового типа UnicodeString , будет рассказано о некоторых новых функциях библиотеки RTL с поддержкой Юникода, а также о специфических средствах написания программ, которые могут понадобиться при программировании. Данная серия статей призвана помочь перейти на кодировку Unicode просто и без лишних усилий.

Заключение

После добавления к среде Delphi поддержки кодировки Unicode как строки по умолчанию стало возможным принимать, обрабатывать и отображать фактически любые существующие в мире алфавиты или кодовые страницы. Приложения, создаваемые в среде Delphi 2009, будут способны принимать, отображать и обрабатывать текст в кодировке Unicode с достаточной простотой, и они будут работать гораздо лучше в любой языковой версии ОС Windows. Разработчики на Delphi смогут теперь с легкостью локализовать и переводить свои приложения, чтобы выйти на рынки, появиться на которых ранее им было гораздо сложнее. Теперь приложения Delphi могут функционировать везде в мире, где необходима поддержка Unicode.

В Части II будут рассмотрены изменения и обновления библиотеки Delphi Runtime Library, которые упрощают работу со строками в кодировке Unicode.

. when altering one's mind becomes as easy as programming a computer, what does it mean to be human.

30 апреля 2010 г.

Работа с текстовыми файлами в любой кодировке из Delphi до 2009

Как должно быть известно любому программисту, не существует такой вещи как "просто текстовый файл". Если вы не знаете, в какой кодировке хранится строка, вы не только не сможете её показать, но даже определить, где она заканчивается.

Мир вокруг нас уже давно не ограничивается ANSI, а уж тем более ASCII. На фоне этого ваши древние ANSI-программы выглядят не очень-то хорошо. Потому что они молчаливо игнорируют существование альтернативных кодировок вообще. Для них существует только текущая кодовая страница ANSI, не больше и не меньше.

Хотя самое нормальное решение включает в себя переход на Delphi 2010, часто вас и пользователей устраивает ваше ANSI-приложение, если бы. оно работало бы с любыми текстовыми файлами. Как это достигается? Ну, в начале текстового файла вставляется метка BOM (Byte Order Mask), указывающая на кодировку файла. Это означает, что если вы хотите загрузить произвольный текстовый файл, то вам нужно прочитать несколько байт в начале файла, после чего определить формат файла и преобразовать его в нужный вам - это довольно много работы, не так ли?

Как это реализуется в Delphi? В Delphi 2009 и выше у вас появляется класс TEncoding, позволяющий работать с различными кодировками. Класс TStrings (и TStringList) используют TEncoding для определения кодировки файла и всех преобразований.

Было бы неплохо заиметь такую штуку, скажем в Delphi 7 или Delphi 2007? К счастью, это очень просто сделать (эй, это заняло примерно 8 минут моего времени, включая проверку). Нужно просто вытащить из Delphi 2010 код TEncoding и новые методы LoadFromFile(Stream)/SaveToFile(Stream).

Представляю вашему вниманию два модуля: Encoding.pas - здесь сидит новый класс TEncoding - штука, полезная сама по себе, даже если вы не используете её для работы с текстовыми файлами.

Второй модуль, StringListUnicodeSupport.pas методом Geo добавляет в обычный TStringList поддержку произвольной кодировки, а также перегруженные варианты методов загрузки и сохранения, позволяющие указать кодировку явно (SaveToFile/Stream сохраняют в ANSI, если вам нужна другая кодировка, вы должны указать её вторым параметром).

Вам достаточно подключить StringListUnicodeSupport в uses и вы волшебным образом получаете возможность работы с любыми текстовыми файлами:
Как пользователи динозаврических Delphi вы, вероятно, не знакомы с TEncoding и перегруженным вариантом методов TStrings. Что ж, к счастью, вы можете воспользоваться online-справкой: TEncoding, использование TEncoging, LoadFromFile, SaveToFile.

Я прочитал этот вопрос, который, как я думал, даст мне то, что я искал:

Я хотел бы знать, есть ли другой способ получить кодировку файла, не используя компонент i18n Mozilla в D2006? Я не могу использовать другие компоненты 3d party.

Я прочитал все ответы из исходного вопроса, и я не могу использовать предоставленный интерфейс, потому что клиент не принимает deployment из этого dll:

Некоторые ссылки, приведенные в исходном вопросе, мертвы, и ни одна из них не решает мою проблему, а именно:
Как получить кодировку файла без использования сторонних компонентов?

2 ответа

Я хотел бы получить версию GCC, используемую для компиляции данного исполняемого файла. Я попробовал readelf , но не получил нужной информации. Есть мысли?

Возможный Дубликат : Как я могу определить кодировку / кодовую страницу текстового файла Как я могу лучше всего угадать кодировку, когда BOM (Знак порядка байтов) отсутствует? Я хотел бы знать, существуют ли некоторые библиотеки delphi для обнаружения character encoding текстового файла.

Я бы сначала поискал BOM, а если он не будет найден, позвоните IsTextUnicode. Но имейте в виду, что ни один метод не является надежным.

Определение кодировки файла представляется проблематичным. Похоже, что некоторые файлы UTF8 не имеют BOM. Это, кажется, работает:

Есть ли лучший подход? Я знаю, что это решение не очень элегантное.

Похожие вопросы:

Как получить имя файла из данного объекта UIImage?

Я знаю, что могу извлечь значок файла с помощью using (System.Drawing.Icon sysicon = System.Drawing.Icon.ExtractAssociatedIcon(filePath)) < icon =.

Возможный Дубликат : Обнаружение кодировки файла в PHP Как я могу выяснить с помощью PHP, какую кодировку файла имеет файл?

Я хотел бы получить версию GCC, используемую для компиляции данного исполняемого файла. Я попробовал readelf , но не получил нужной информации. Есть мысли?

Возможный Дубликат : Как я могу определить кодировку / кодовую страницу текстового файла Как я могу лучше всего угадать кодировку, когда BOM (Знак порядка байтов) отсутствует? Я хотел бы знать.

Передо мной стоит задача создать автоматизированный релиз для устаревшего проекта Delphi (Delphi 2006). Я полный нуб Delphi. Так что мой вопрос, возможно, движется в неправильном направлении .

Есть ли встроенный способ получить стандартное расширение данного типа MIME в Delphi (XE7)? Я ищу самый простой и общий способ реализации функции, которая будет называться следующим образом: fileExt.

Мне нужно иметь функциональность в моем приложении delphi, чтобы получить общее время длительности данного файла Powerpoint (формат pptx). Кто-нибудь, кто может заставить меня идти? Большое спасибо.

Мне нужно определить кодировку символов содержимого файла .csv. Каждый фрагмент кода, который я видел, использует file_get_contents() , однако я не могу использовать его, потому что файл слишком.

В данной статье рассматриваются новые функции библиотеки Tiburon Runtime Library, которые помогают обрабатывать строки Unicode.

Введение

В Части I было показано, какие выгоды дает разработчикам на Delphi поддержка кодировки Unicode, позволяя работать со всеми наборами символов в кодировке Unicode. Были рассмотрены основные особенности типа строки UnicodeString и было показано, как его можно использовать в Delphi.

В части II будет рассказано о некоторых новых функциях библиотеки Delphi Runtime Library, предназначенных для поддержки Unicode, и общих методах обработки строк.

Класс TCharacter

  • преобразование символов в верхний или нижний регистр;
  • определение типа данного символа, то есть является ли символ буквой, цифрой, знаком препинания и так далее.

Классом TCharacter используются стандарты, установленные организацией Unicode consortium.

Разработчики могут использовать класс TCharacter для выполнения многих действий, выполнявшихся до этого с наборами символов. Например, следующий программный код:

Модуль Character содержит также ряд автономных функций, которые выполняют функции каждой из функций класса TCharacter, так что если предпочтительнее простой вызов функции, приведенный выше программный код можно переписать как:

Таким образом, класс TCharacter можно использовать для выполнения многих действий или проверки символов, которая может понадобиться.

Кроме того, класс TCharacter содержит методы класса, позволяющие определить, является ли символ верхним или нижним суррогатом суррогатной пары.

Класс TEncoding

Библиотека Tiburon RTL также включает новый класс TEncoding. Его назначение - определить конкретный тип кодировки символов, чтобы можно было сообщить библиотеке VCL, какой тип кодировки необходимо использовать в конкретных ситуациях.

Например, пусть есть экземпляр TStringList, содержащий текст, который необходимо записать в файл. Ранее необходимо было бы написать

и файл записался бы, по умолчанию, в кодировке ANSI. Данный код по-прежнему хорошо работает - файл запишется им в кодировке ANSI, как и раньше, но теперь, когда в Delphi поддерживаются строковые данные в кодировке Unicode, разработчикам может потребоваться записать строковые данные в какой-либо конкретной кодировке. Поэтому оператор SaveToFile (а также LoadFromFile) теперь имеет дополнительный второй параметр, которым определяется используемая кодировка:

При выполнении приведенного выше кода файл будет записан как текстовый файл в кодировке Unicode (UTF-16).

Классом TEncoding будет также преобразовываться заданный набор байтов из одной кодировки в другую, извлекаться информация о байтах и/или символах в заданной строке или массиве символов, преобразовываться любая строка в массив array of byte (TBytes) и выполняться другие функции, которые могут потребоваться для конкретной кодировки заданной строки или заданного массива символов.

Класс TEncoding включает следующие свойства класса, дающие доступ к экземпляру TEncoding заданной кодировки:

Свойство Default ссылается на активную кодовую страницу ANSI. Свойство Unicode ссылается на UTF-16.

Класс TEncoding также включает функцию

которая будет возвращать экземпляр TEncoding, соответствующий кодовой странице, переданной в параметре.

Кроме того, он включает следующую функцию:

которая будет возвращать правильный маркер порядка байтов для заданной кодировки.

TStringBuilder

Библиотека RTL теперь включает класс TStringBuilder. Его назначение ясно из его названия - это класс, предназначенный для создания строк. Класс TStringBuilder содержит большое количество перегружаемых функций для добавления, замены и вставки содержимого в заданную строку. Этот класс упрощает создание единых строк из множества различных типов данных. Каждая из функций Append, Insert и Replace возвращает экземпляр класса TStringBuilder, поэтому их можно легко объединять для создания единой строки.

Например, можно использовать класс TStringBuilder вместо усложненного оператора Format. Например, можно написать следующий программный код:

Объявление новых типов строк

Компилятор Tiburon позволяет объявить собственный тип строки, связанный с заданной кодовой страницей. Доступно любое число кодовых страниц. Например, если необходим тип строки, соответствующий кодировке ANSI-кириллице, можно объявить:

И новый тип строки будет соответствовать кодовой странице кириллицы.

Дополнительная поддержка Unicodeбиблиотекой RTL

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

StringElementSize

Подпрограммой StringElementSize возвращается типичный размер элемента (элемента кода) в заданной строке. Рассмотрим следующий код:

Результатом выполнения приведенного выше кода будет:

StringCodePage

Подпрограммой StringCodePage будет возвращаться значение Word, которое соответствует кодовой странице для заданной строки.

Рассмотрим следующий код:

Результатом выполнения приведенного выше кода будет:

Другие функции библиотеки RTL, связанные с кодировкой Unicode

  • UnicodeStringToUCS4String
  • UCS4StringToUnicodeString
  • UnicodeToUtf8
  • Utf8ToUnicode

Кроме того, в библиотеке RTL также появился тип RawByteString, который представляет собой тип строки, не связанный ни с какой кодировкой:

Тип RawByteString позволяет передавать строковые данные для любой кодовой страницы без каких-либо преобразований последней. Он особенно полезен для подпрограмм, для которых кодировка не имеет значения, например для побайтового поиска в строке. Обычно это означает, что параметры подпрограмм, которыми обрабатываются строки без связи с их кодовыми страницами, должны иметь тип RawByteString. Тип RawByteString следует присваивать переменным как можно реже, если вообще когда-либо, так как это может привести к непредсказуемому поведению и возможной потере данных.

Как правило, присвоения типов строк совместимы друг с другом.

будет выполнено, как и ожидалось - содержимое строки типа AnsiString будет помещено в строку типа UnicodeString. Как правило, можно присваивать один тип строки строке другого типа, и компилятор выполнит необходимые преобразования, если возможно.

Однако некоторые преобразования могут привести к потере данных, и необходимо остерегаться при перемещении из строки одного типа, которая включает данные в кодировке Unicode, в другую, тип которой не поддерживает Unicode. Например, можно присваивать тип UnicodeString строке типа AnsiString, но если строка типа UnicodeString содержит символы, которые не отображаются в активной в данный момент кодовой странице ANSI, то эти символы будут потеряны при преобразовании. Рассмотрим следующий код:

Результат выполнения этого кода, если текущая кодовая страница ОС - 1252, будет следующим:

Как можно видеть, при назначении типа UnicodeString строке типа AnsiString информация теряется, так как символы кириллицы не отображаются кодовой страницей Windows-1252. Причина такого результата - строка UnicodeString содержала символы, не представимые в кодовой странице AnsiString, эти символы были потеряны и заменены вопросительными знаками при назначении типа UnicodeString строке типа AnsiString.

SetCodePage

Функция SetCodePage, объявленная в модуле System.pas как

представляет собой новую функцию RTL, которой задается новая кодовая страница для строки типа AnsiString. Необязательным параметром Convert определяется, следует ли преобразовать сами данные строки в заданную кодовую страницу. Если значение параметра Convert - False, то для строки просто будет изменена кодовая страница. Если значение параметра Convert - True, то данные передаваемой строки будут преобразованы в заданную кодовую страницу.

Функция SetCodePage должна использоваться редко и с большой осторожностью. Обратите внимание, что, если кодовая страница не соответствует существующим данным строки (то есть значение параметра Convert - False), то результаты могут оказаться непредсказуемыми. Кроме того, если существующие данные строки преобразованы, а в новой кодовой странице не представлен заданный исходный символ, данные могут потеряться.

Получение массива байтов TBytesиз строк

В составе библиотеки RTL есть также набор перегружаемых подпрограмм для извлечения из строки массива байтов. Как будет показано в части III, рекомендуется использовать в качестве буфера данных массив TBytes, а не строку. Библиотека RTL упрощает это за счет перегружаемых версий функции BytesOf(), принимающей в качестве параметра разные типы строк.

Заключение

Библиотека Tiburon's Runtime Library теперь полностью поддерживает новый тип строки UnicodeString. В нее входят новые классы и подпрограммы для обработки и преобразования строк в кодировке Unicode, для управления кодовыми страницами и для упрощения перехода с более ранних версий.

В Части III будут рассмотрены специальные кодовые конструкции, которые необходимы, чтобы выяснить: готов ли тот или иной программный код к переходу на кодировку Unicode.

Читайте также: