Содержание
- Содержание
- Введение
- Страхи перед UTF-8
- Неоспоримые плюсы UTF-8
- Ответы на частые вопросы и заблуждения по кодировкам
- Вывод
- Дополнительная информация по теме
- Общее определение кодировки
- Богатство разнообразия кодовых таблиц
- Некорректное отображение символов
- Кириллическая таблица ANSI-кодировок, Windows-1251
- Подводя итоги
- Краткая история кодировок:
✍
Работая над проектом интернет магазина столкнулся, с проблемой кодировки в компонентах движка.Проблема была не в оригинальных файлах магазина, которые как и пологается были в кодировке UTF-8, а во врезаемых модулях которые были в кодировке CP-1251, потому что писались к предыдущим версиям CMS где всё было в кодировке Windows-1251. Кроме этого встретил модули и их модификации где была смешанная кодировка: код в Utf-8, а различные сообщения на кириллице в Cp-1251.
В начале пробовал изменять кодировку при помощи редактора Akelpad, но по неизвестной причине это не смогло решить проблему, да и файлов было довольно много подлежащих к изменению.Возникшею проблему удалось решить при помощи простой и удобной программы
⚠ ↓
Только по этим ссылкам ↓, заходя на ALI, и совершая заказы у любого продавца, вы поддерживаете автора Социального проекта для незрячих и слабовидящих NVDA.RUили можно отправить Donate
Моё Описание программы EncodingConverter
Для запуска программы EncodingConverter,
- открываем одноименный файл EncodingConverter. exe.
- В начале через кнопку обзор выбираем папку с файлами
- Затем в выпадающим списке выбираем новую кодировку.
- UTF-8 без BOM
- UTF-8 с BOM
- UTF-16-Le
- UTF-16-BE
- UTF-32-LE
- UTF-32-BE
- CP-1251
- В поле фильтр, нам нужно дописать те расширение файлов, в которых будем изменять кодировку.
- Перед тем как нажать кнопку начала изменения кодировки, нажмите на кнопку анализировать.
Вот так всё просто в этой программе, спасибо за это автору.Не забывайте все такие фокусы производить всегда на копиях файлов.
Где скачать EncodingConverter
А скачать эту версию программы EncodingConverter, которую я сам использую можно с моего сайта.Скачать EncodingConverterРазмер архива Zip примерно 23 KB.
Поделиться
Если не работает ссылка?
Если вдруг ссылка стала не рабочей, пожалуйста, скопируйте ссылку из адресной строки браузера на эту страницу и отправьте её мне черезФорму обратной связи в теме сообщения выбрав подходящию тему. Благодарю вас за понимание.
Содержание
Страница создана: 2011-07-15, обновлена: 2017-10-27
Введение
Читая на просторах интернета споры про кодировки UTF-8 и cp1251 решил подытожить и всю муть изложить коротко.
Примечание: UTF-8 иногда пишется просто как UTF. Также еще имеется кодировка UTF16, но она в основном касается китайских языков, поэтому рассматривать ее в дальнейшем не имеет смысла. Не нужно путать с Unicode! Unicode (Юникод) – это универсальное кодирование, а UTF-8 – это кодировка на базе Unicode!
Сразу и смело можно перефразировать вопрос и знающие люди поймут. UTF или не UTF? То есть, я за UTF-8 – однозначно!
Страхи перед UTF-8
- Не поддержка старых (рабочих) проектов кодировки UTF-8. (Давайте еще ДОС вспомним). Ориентироваться на старые продукты, считаю полностью утопично.
- Один символ кириллицы в cp1251 занимает 1 байт, а в utf-8 – 2 байта. Как ни странно данный факт сильно отталкивает, и отталкивал меня долгое время от начало использования данной кодировки. Как показала практика в среднем UTF страница на русском языке больше, чем стандартная cp1251 всего на 20-30 процентов. Если текст на английском, то страница одинакового размера. Чаще всего – основной вес страницы составляет HTML код, JavaScript, Flash, картинки, CSS и так далее. Тем, кто заботится о «весе», следовало бы в первую очередь выкинуть из кода подстановки для тех символов, которым они не нужны, например, «- » для длинного тире или для неразрывного пробела (ой, как часто я вижу это в страницах новичков). Видим, что вместо 1 знака длинного тире мы пишем 6, вместо 1 знака неразрывного пробела мы пишем 5 знаков. И где же экономия? Действительно, иногда доходит до маразма – некто упирается: «Не буду делать страницы в UTF-8, потому что они от этого увеличиваются» – а сам при этом ваяет код с жуткими атрибутами и подстановками, который без них мог бы быть в пять раз короче. Также у 90 процентов WEB программистов HTML страницы просто не оптимизированы, даже пробелы не убраны из кода. А пробел это тоже байтик!
- отображения крокозябликов в любимых стареньких программах, таких как Far. Не знаю почему, но far так не сумел приучить читать корректно данную кодировку даже в последнем beta релизе Far 2.0.
Неоспоримые плюсы UTF-8
- старые кодировки, таких как cp1251 или KOI8R, предоставляли не более 256 символов, а в Unicode есть свыше 100 000 символов, среди них – типографские знаки (тире, кавычки, многоточие, апостроф, неразрывный пробел неразрывный дефис и прочие прикольные символы);
- специальные символы №, §, ©, ‰, «», …, × и прочее. Например, это очень актуально на сайтах с кулинарной тематикой, где употребляются различные дробные меры такие как ½, ⅓, ¼, ⅔, ¾ и так далее. А как же быть с финансовой тематикой? Сейчас сложно представить нормальный сайт, где бы не указывался значки валют в ценниках, например, ȼ ¥ £ €. Повторите тоже самое на cp1251 или будете целые картинки подгружать вместо одного символа?
- буквы с диакритическими знаками и лигатуры (é, è, Ü, Æ, ø, fi и прочее);
- символы почти всех существующих в мире алфавитов (α, Ω, א, ת,, 伲, 儻 и прочее);
- пиктограммы и значки (→, ■, ♥, ☺ и прочее);
- множество других полезных символов.
Самое классное в этом всем это то, что все эти символы можно вставлять непосредственно в редакторе (из таблицы символов или с помощью горячих клавиш), что делает код куда более читабельным, нежели использование кракозяб вроде µ – или π (альтернативы в cp1251).
Примечание: Помнится в конце 90 линуксоиды кричали, что KOI-8 рулит и победит cp1251, но как оказалось эта кодировка померла раньше.
- Универсальность! Благодаря utf-8 можно создавать сайты без каких-либо переделок как для американцев, так и для немцев (с их буквочками вроде Ü), так и для арабов, так и для китайцев! И все равно, какая кодировка у них установлена, а какая нет, ибо Юникод у них установлен 100 процентов. Например, если у вас сайт публикует новости сразу на русском и немецком языке, то эту UTF с этим легко справляется, а вот уже на cp1251 это сделать невозможно.
- Юникод является стандартом для работы таких часто используемых ныне функций PHP , как json_encode/json_decode, а так же используемого в AJAX XHttpRequest. Причем, начиная с 6й версии PHP Юникод станет стандартом для всех строковых функций. Поэтому на много быстрее и удобнее скармливать данные уже в UTF кодировке а не конвертировать постоянно, потому как все равно функции PHP и JavaScript будут это требовать. То есть, если вы хотите работать с такими технологиями как XML, JSON, AJAX и прочие современные технологии, то вам придется переходить на UTF-8, ибо со времен своего основания они работают только в этой кодировке.
- Поисковые системы значительно лучше относятся к сайтам на UTF-8 кодировке, чем на какой-либо другой. Многие скажут, что это спорный момент, однако проводился эксперимент, на 10 сайтах. Один и тот же контент, тот же дизайн, тот же хостер, разные были только кодировки. Не поверите, но сайт на UTF кодировке стоял выше в поисковых позициях. Вот такой вот фокус.
- Для быстрой индексации сайта в поисковых системах Yandex и Google используется файлик sitemap.xml, как ни странно, но работает он только если сделан в UTF, иначе поисковые системы ругаются.
- И напоследок, многие ссылаются на то, что люди постепенно переходят на utf-8 потому, что «кто-то умный сказал, что это хорошо». Соглашусь, кто-то умный это сказал уже давно, а именно – Консорциум W3C (кому-то эти 3 буквы что-то говорят? И рекомендует он использовать для создания WEB страниц ни что иное, как utf-8. Для тех, кто знает английский (а есть программисты, кто его не знает? Можете почитать.
Ответы на частые вопросы и заблуждения по кодировкам
У меня сайт только на русском языке и на всякие китайские языки я переходить не намерен
Очень интересное заблуждение. Если у Вас один проект, то тут соглашусь, что особо не стоит заморачиваться на эту тему. Если проектов много то уже очень скоро столкнетесь с проблемами. Ведь UTF это не только разные языки, но и как я уже говорил, это довольно сложные математические функции и многое другое 🙂 А математика есть в любом языке, в том числе и на русском.
Терминалы не поддерживают utf-8 (ssh, ssl, terminal)
Какой бред. Я вам ответственно заявляю, как программист, что все терминалы не испытывают никаких проблем с utf, да им это особо и не требуется, так как в основном они пишут все на английском языке.
Постоянная проблемы с BOM заголовком
Никаких проблем вообще не возникает. Напомню, что BOM заголовок в текстовых документах был придумал как дополнение, чтобы по быстрому определяться и в дальнейшем определять в какой кодировке записан текстовой документ. BOM заголовок это принятый стандарт, если вы программист, то научитесь обрабатывать грамотно всего три байта. Если вы профи, то я думаю вы справитесь с этой «мега» задачей в три байта. Если Вы обычный пользователь, то не заморачивайтесь на счет этого заголовка, просто его не прописывайте.
Постоянный геморрой в PHP с использованием функций mb_
1. Если у вас вызывает неприятность функции в добавлением всего 2 буковок, может программирование не ваш конек?
2. В PHP 5.0 обычные функции strpos и подобные легко и прекрасно работают с кодировкой UTF. Смотрите подробнее init_charset в PHP. Есть ряд переключателей которые легко переключают весь PHP движок на работу с нужной кодировкой по умолчанию.
3. В PHP 6.0, как я уже говорил (смотрите официальный сайт PHP) UTF-8 будет кодировкой по умолчанию. Вам нужен лишний геморрой в дальнейшем при переносе проектов? В свое время тоже все считали, что PHP 3.0 удовлетворяет всем потребностям, но не заметили как уже докатились до PHP 5.0.
4. JavaScript с самого момента своего создания работал только с кодировкой UTF. Все, что вы видите на JS в cp1251 это метаморфозы на уровне ядра. Об этом можете легко прочитать на официальном сайте JavaScript на Sun Мастерс.
5. Основная в базах данных также по умолчанию теперь только UTF-8. Смотрите и читайте соответствующие спецификации.
Если у меня старый проект на cp1251 работает стабильно, нужно ли переносить на UTF?
Если рассуждать рационально, то нет. Но если вы в дальнейшем планируете свой старый проект еще перерабатывать и дополнять новыми функциями, то стоит обдумать, но перед этим 1000 раз все взвешать.
UTF это бред, так как мой редактор его не поддерживает
Ваш редактор не пуп земли. И если у вас есть такой редактор, который не поддерживает данной кодировки, то это уже бездарность. Напомню, что начиная с выпуска Windows XP даже пресловутый Windows блокнот знает и корректно открывает текстовые документы в UTF кодировке. А также начиная с системы Windows Vista кодировка UTF считается кодировкой по умолчанию. Не питайте иллюзий, что Windows до сих пор сидит на своей родной кодировке cp1251. Это было сделано только для поддержки старых программ не более. Рекомендую по чаще заходить на сайт Microsoft и интересоваться ихними направлениями развития и технологиями. Откроете для себя много интересного, а главное, ваши знания будут уже не на уровне только слухов.
Все браузеры по умолчанию настроены на cp1251
Мда, как тут все запущено. В любом браузере есть галочка, авто определение кодировки. Какой тег на странице у вас будет прописан такую кодировку и будет браузер применять по умолчанию. Напоминаю код который управляет кодировкой на странице:
В cp1251 одна буква, так одна буква, а в юникоде это xAB и uABCD
Ребята, не нужно путать теплое с мягким. А именно не нужно путать отображение и фактическим состоянием. То есть, UTF он как шифровался в 1-2 байт так и шифруется (UTF-16 не беру в данном случае в расчет), а отображается может хоть как. Как говорится на заборе тоже написано «…», но за забором то картошка. Не плохо было бы иногда все таки заглядывать за забор.
Это все к тому, что та же единица (1) может отображаться как:
- 00000001 – двоичная система
- 01 – шестнадцатеричная система счисления
- 1 – десятичная
и так далее. Здесь тоже самое.
Написал charset utf-8 сайт все равно открывается в cp1251
Вариантов может быть много, но есть частые ошибки.
1. Неправильно прописан meta http-equiv. Нужно писать charset=utf-8, у многих charset=utf8. Как ни странно, но тире играет большую роль почему то.
2. Прописав charset=utf-8 в мета, требуется еще и саму страницу конвертировать в эту кодировку, но многие считают, что типа этого делать не нужно.
3. Проблема при выводе информации из базы данных MySQL при помощи PHP. Более детально эта, ошибка расписана в статье «Как вывести данные в PHP из таблицы MySQL?»
Вот коротко ответил на самые частые утверждения, вопросы и заблуждения. По мере поступления буду дополнять и отвечать здесь.
Вывод
Люди утверждающие, что cp1251 лучше, чем UTF-8, это как те аборигены, которые в свое время считали, что земля плоская и человек есть пуп земли. А именно у таких людей преобладает лень к стремлению к новым вершинам, или тяжело ломать старые стереотипы, или тупо, боязнь того что, как это у других может быть лучше, чем у меня, нет уж если я в дерьме, то и новички тоже пускай в дерьме сидят, а то одному то скучно 😉 Ээх человечество.
Дополнительная информация по теме
Какая разница в кавычках PHP
Описание основной разницы между кавычками, а также наглядные примеры разницы в скорости работы при употреблении разных кавычек
Рейтинг мониторов – лучшее, 2015 год
Сравнительный рейтинг мониторов различных классов с актуальностью на начало 2015 года
Рейтинг кофеварок – лучшее, 2015 год
В статье составлен рейтинг лучших кофеварок для дома, описаны все достоинства и недостатки представленных моделей, на основе чего и выбрана лучшая кофеварка
Рейтинг мониторов, лучшее – 2015 год
Статья о положении дел на рынке мониторов, рейтинге мониторов на начало 2015 года, о смене старых технологий на новые
Прежде чем отвечать на вопрос о том, что же такое кодировка ANSI Windows, ответим сначала на другой вопрос: “Что же такое кодировка вообще?”
У каждого компьютера, в каждой системе используется определенный набор символов, зависящий от языка, используемого пользователем, от его профессиональных компетенций и личных предпочтений.
Общее определение кодировки
Так, в русском языке используется 33 символа для обозначения букв, в английском – 26. Также используется 10 цифр для счета (0; 1; 2; 3; 4; 5; 6; 7; 8; 9) и некоторые специальные символы, в том числе запятая, минус, пробел, точка, процент и так далее.
Каждому из этих символов при помощи кодовой таблицы присваивается порядковый номер. К примеру, букве “A” может быть присвоен номер 1; “Z” – 26 и так далее.
Собственно, номер, представляющий символ как целое число, считается кодом символа, а кодировка – это, соответственно, набор символов в такой таблице.
Богатство разнообразия кодовых таблиц
На данный момент существует довольно большое количество кодировок и кодовых таблиц, используемых разными специалистами: это и ASCII, разработанная в 1963 году в Америке, и Windows-1251, совсем недавно еще бывшая популярной благодаря Microsoft, KOI8-R и Guobiao – и многие, многие другие, причем процесс их появления и отмирания происходит и по сей день.
Среди этого огромного списка совершенно особо держится так называемая кодировка ANSI.
Дело в том, что в свое время компания Microsoft создала целый набор кодовых страниц:
Windows – 874 | Тайский |
Windows-1250 | Центральноевропейский |
Windows-1251 | Кириллический (все символы русского языка + символы близких языков) |
Windows-1252 | Западноевропейский |
Windows-1253 | Греческий |
Windows-1254 | Турецкий |
Windows-1255 | Еврейский |
Windows-1256 | Арабский |
Windows-1257 | Балтийский |
Windows-1258 | Вьетнамский |
Все они получили общее название таблицы кодировки ANSI, или кодовой страницы ANSI.
Интересный факт: одной из первых кодовых таблиц стала ASCII, в 1963 году созданная American National Standards Institute (Американским национальным институтом стандартов), сокращенно называвшимся именно ANSI.
Помимо всего прочего, эта кодировка содержит и непечатные символы, так называемые “Управляющие последовательности”, или ESC, уникальные для всех таблиц символов, зачастую несовместимые между собой. При умелом использовании, однако, они позволяли скрывать и восстанавливать курсор, переводить его с одного положения в тексте на другое, устанавливать табуляцию, стирать часть окна терминала, в котором велась работа, изменять форматирование текста на экране и менять цвет (или даже рисовать и подавать звуковые сигналы!). В 1976 году, кстати, это было довольно неплохим подспорьем для программистов. Кстати, терминал – это устройство, требующееся для ввода и вывода информации. В те далекие времена он представлял собой монитор и клавиатуру, подсоединенные к ЭВМ (электронной вычислительной машине).
Некорректное отображение символов
К сожалению, в дальнейшем подобная система вызвала многочисленные сбои в системах, выводя вместо желаемых стихов, лент новостей или описаний любимых компьютерных игр так называемые кракозябры – бессмысленные, нечитаемые наборы символов. Появление этих вездесущих ошибок было вызвано всего лишь попыткой отображать символы, закодированные в одной кодовой таблице, при помощи другой.
Чаще всего с последствиями неверного чтения этой кодировки мы сталкиваемся в Интернете до сих пор, когда наш браузер по какой-то причине не может достаточно точно определить, какая именно из Windows-**** кодировок используется в данный момент, из-за указания веб-мастером общей кодировки ANSI либо изначально неверной кодировки, к примеру, 1252 вместо 1521. Ниже представлена точная таблица кодировок.
Кириллическая таблица ANSI-кодировок, Windows-1251
№ П/п.
HEX
СИМВОЛ
№ П/п.
HEX
СИМВОЛ
№ П/п.
HEX
СИМВОЛ
000
00
NOP
086
56
V
171
AB
«
001
01
SOH
087
57
W
172
AC
¬
002
02
STX
088
58
X
173
AD
003
03
ETX
089
59
Y
174
AE
®
004
04
EOT
090
5A
Z
175
AF
Ї
005
05
ENQ
091
5B
[
176
B0
°
006
06
ACK
092
5C
177
B1
±
007
07
BEL
093
5D
]
178
B2
І
008
08
BS
094
5E
^
179
B3
і
009
09
TAB
095
5F
_
180
B4
ґ
010
0A
LF
096
60
`
181
B5
µ
011
0B
VT
097
61
a
182
B6
¶
012
0C
FF
098
62
b
183
B7
·
013
0D
CR
099
63
c
184
B8
Е
014
0E
SO
100
64
d
185
B9
№
015
0F
SI
101
65
e
186
BA
Є
016
10
DLE
102
66
f
187
BB
»
017
11
DC1
103
67
g
188
BC
ј
018
12
DC2
104
68
h
189
BD
Ѕ
019
13
DC3
105
69
i
190
BE
Ѕ
020
14
DC4
106
6A
j
191
BF
Ї
021
15
NAK
107
6B
k
192
C0
А
022
16
SYN
108
6C
l
193
C1
Б
023
17
ETB
109
6D
m
194
C2
В
024
18
CAN
110
6E
n
195
C3
Г
025
19
EM
111
6F
o
196
C4
Д
026
1A
SUB
112
70
p
197
C5
Е
027
1B
ESC
113
71
q
198
C6
Ж
028
1C
FS
114
72
r
199
C7
З
029
1D
GS
115
73
s
200
C8
И
030
1E
RS
116
74
t
201
C9
Й
031
1F
US
117
75
u
202
CA
К
032
20
Пробел
118
76
v
203
CB
Л
033
21
!
119
77
w
204
CC
М
034
22
«
120
78
x
205
CD
Н
035
23
#
121
79
y
206
CE
О
036
24
$
122
7A
z
207
CF
П
037
25
%
123
7B
{
208
D0
Р
038
26
&
124
7C
|
209
D1
С
039
27
‘
125
7D
}
210
D2
Т
040
28
(
126
7E
~
211
D3
У
041
29
)
127
7F
212
D4
Ф
042
2A
*
128
80
Ђ
213
D5
Х
043
2B
+
129
81
Ѓ
214
D6
Ц
044
2C
,
130
82
‚
215
D7
Ч
045
2D
—
131
83
ѓ
216
D8
Ш
046
2E
.
132
84
„
217
D9
Щ
047
2F
/
133
85
…
218
DA
Ъ
048
30
134
86
†
219
DB
Ы
049
31
1
135
87
‡
220
DC
Ь
050
32
2
136
88
€
221
DD
Э
051
33
3
137
89
‰
222
DE
Ю
052
34
4
138
8A
Љ
223
DF
Я
053
35
5
139
8B
‹
224
E0
а
054
36
6
140
8C
Њ
225
E1
б
055
37
7
141
8D
Ќ
226
E2
в
056
38
8
142
8E
Ћ
227
E3
г
057
39
9
143
8F
Џ
228
E4
д
058
3A
:
144
90
Ђ
229
E5
е
059
3B
;
145
91
‘
230
E6
ж
060
3C
<</sup>
146
92
’
231
E7
з
061
3D
=
147
93
“
232
E8
и
062
3E
>
148
94
”
233
E9
й
063
3F
?
149
95
•
234
EA
к
064
40
@
150
96
–
235
EB
л
065
41
A
151
97
—
236
EC
м
066
42
B
152
98
237
ED
н
067
43
C
153
99
™
238
EE
о
068
44
D
154
9A
љ
239
EF
п
069
45
E
155
9B
›
240
F0
р
070
46
F
156
9C
њ
241
F1
с
071
47
G
157
9D
ќ
242
F2
т
072
48
H
158
9E
ћ
243
F3
у
073
49
I
159
9F
џ
244
F4
ф
074
4A
J
160
A0
245
F5
х
075
4B
K
161
A1
Ў
246
F6
ц
076
4C
L
162
A2
ў
247
F7
ч
077
4D
M
163
A3
Ј
248
F8
ш
078
4E
N
164
A4
¤
249
F9
щ
079
4F
O
165
A5
Ґ
250
FA
ъ
080
50
P
166
A6
¦
251
FB
ы
081
51
Q
167
A7
§
252
FC
ь
082
52
R
168
A8
Е
253
FD
э
083
53
S
169
A9
©
254
FE
ю
084
54
T
170
AA
Є
255
FF
я
085
55
U
Более того, в 1986 году ANSI была существенно расширена, благодаря Яну Э. Дэвису, написавшему пакет The Draw, позволяющий не просто использовать базовые, с нашей точки зрения, функции, но и полноценно (или почти полноценно) рисовать!
Подводя итоги
Таким образом, можно видеть, что кодировка ANSI, по сути, хоть и была довольно спорным решением, сохраняет свои позиции.
Со временем с легкой руки энтузиастов древний терминал ANSI перекочевал даже на телефоны!
Сколько постов написано в блогах, сколько вопросов задано на форумах о кодировках и ещё большее количество подобных вопросов осталось не отвеченными или ответом было что-то наподобие “Поиском пользовались?” или “Сто раз обсуждалось!!!”. Честно говоря, никогда не понимал таких “ответчиков”, ИМХО не хочешь отвечать – лучше жуй и молчи, ответят те, кто захочет. Понятное дело, что обучать иногда приходится не только с помощью пряника, но и с помощью кнута, но, раз уж такие вопросы всё время всплывают, следовательно они остаются актуальными. Сегодня я попробую рассказать Вам всё, что мне известно о работе с кодировками в тексте. Вполне возможно, что эта статья поможет Вам при разработке своих проектов в Delphi да и у меня уже пару раз возникало желание немного систематизировать ту информацию. которая накопилась за время существования блога.
Содержание скрыть 1 1. Delphi и Unicode 2 2. Подготовка исходных данных для работы 3 3. Массив байтов – в нормальный текст 4 3.1. Работа с TEncoding 5 3.2. Использование возможностей MLang для работы с кодовыми страницами 6 3.3. Использование методов System.pas для перекодирования текста
1. Delphi и Unicode
Если говорить о работе с Unicode в Delphi, то начать стоит с того, что полноценная поддержка unicode в Delphi стала возможна лишь после выхода Delphi 2009. Такое событие не могло пройти незамеченным, так как благодаря поддержке Unicode и, соответственно, для облегчения работы с кодировками текста в Delphi были реализованы новые возможности, методы, типы данных, о которых написано большое количество статей. На мой взгляд одной из лучших публикаций на эту темя является цикл из трех статей “Delphi и кодировка Unicode” где достаточно чётко и доступно рассказано о нововведениях Delphi 2009 для работы с unicod’ом. Думаю, что нет смысла подробно останавливаться на всех новшествах при наличии ссылки на целых три статьи на эту тему. Остается только упомянуть о том, с чем мы сегодня будем работать для представления веб-страницы в нормальном читаемом виде. Для первого способа работы с кодировкой мы воспользуемся:
- Класс TEncoding, который и дает нам возможность без лишних хлопот работать с кодировками
- Тип данных TBytes – массива байтов строк
- RawByteString – тип для передачи строковых данных для любой кодовой страницы без каких-либо преобразований последней
В одной из статей блога рассматривалась работа с MLang и сегодня, в качестве второго способа, я продемонстрирую Вам пример её применения при работе с кодировками. Ну и в качестве третьего способа работы с кодировками, воспользуемся “штатными” методами модуля system. Все три варианта работы с кодировками приведут к одному и тому же результату – текст веб-страницы будет читаемым, без “кракозябров” и вопросительных знаков. Какой способ лучше – решать только Вам.
with THTTPSend.Create do begin if HTTPMethod('GET',URL)then begin //в свойстве Document объекта THTTPSend содержится исходник страницы //обрабатываем Document end; end;
Теперь, получив данные (свойство Document:TMemoryStream) скопируем эти данные в массив байтов строки TBytes, например так (способ достаточно медленный, приведен исключительно для примера):
var B: TBytes; i:integer; begin //загружаем контент страницы with THTTPSend.Create do begin if HTTPMethod('GET',URL) then begin Document.Position:= ; SetLength(B,Document.Size); for i := to Document.Size - 1 do Document.Read(B[i],1); end; end;
Первый этап подготовки можно считать законченным – у нас есть массив байтов строки, которые необходимо представить в виде текста в правильной кодировке. А как узнать, что наш массив TBytes надо перевести в новую “правильную” кодировку? Естественно узнать в какой кодировке была исходная страница. Здесь можно пойти двумя путями: 1. Узнать кодировку из мета-тегов. Обычно кодировка страницы описывается мета-тегом следующего содержания:
META http-equiv="content-type" content="text/html; charset=windows-1251
. Пример того как узнать кодировку из мета-тегов страницы Вы можете посмотреть в модуле HtmlCPConvert, который я выкладывал в блоге, когда рассматривал работу с MLang. 2. Узнать кодировку текста из заголовков сервера. Если рассматривать этот пример, используя для работу с HTTP
HTTP (Hyper Text Transfer Protocol) – это базирующийся на TCP/IP протокол передачи гипертекста, обеспечивающий доступ к документам на web-узлах.” target=”_blank” >HTTP-протоколом библиотеку Synapse, то заголовки сервера будут содержаться в свойстве Headers:TStringList. Найти элемент, содержащий сведения о кодировке и получить имя кодовой страницы можно, например так:
function GetCharset(Headers: TStringList): string; var i:integer; begin if Headers.Count= then Exit; for I := to Headers.Count - 1 do begin //Content-Type: text/html; charset=UTF-8 if Pos('content-type',LowerCase(Headers[i]))> then if pos('=',Headers[i])> then Result:=LowerCase(Copy(Headers[i],pos('=',Headers[i])+1,Length(Headers[i])-pos('=',Headers[i]))) else Result:=DefCharset; end; end;
3. Массив байтов – в нормальный текст
3.1. Работа с TEncoding
Разработчики Delphi предусмотрели использование двух взаимопротивоположных метода:
- function BytesOf(const Val: RawByteString): TBytes; – получение байтов из строки
- function StringOf(const Bytes: TBytes): UnicodeString; – получение строки из массива байтов
Пусть Вас не пугает то, что StringOf возвращает UnicodeString, т.к., начиная с Delphi 2009
type UnicodeString = string
Теперь, что касается непосредственно работы с TEncoding. Во-первых, от нас не требуется создавать отдельный экземпляр класса, наподобие такого:
var Enc: TEncoding; begin Enc:=TEncoding.Create; end;
Во-вторых, с помощью TEncoding мы можем менять кодовую страницу не преобразовывая массив байтов в строку. Для этого класс содержит следующие классовые методы:
class function Convert(Source, Destination: TEncoding; Bytes: TBytes): TBytes; overload; class function Convert(Source, Destination: TEncoding; Bytes: TBytes; StartIndex, Count: Integer): TBytes; overload;
Одним из этих методов мы и воспользуемся. Для того, чтобы продемонстрировать работу с TEncoding попробуем получить текст прямо из этого блога. Кодировка UTF-8, именно она наиболее часто является “проблемной” и возвращает в TMemo или ещё куда-либо “кракозябры”. Создадим простое приложение как показано на рисунке: В ComboBox сразу занесем все варианты работы с текстом:
- Без преобразования
- TEncoding (модуль SysUtils)
- MLang
- Utf8ToAnsi (модуль System)
По нажатию кнопки TButton будем грузить страницу в массив байтов и, зависимости от выбранного варианта работы с текстом, преобразовывать массив в строку и выводить в Memo. Для первого варианта (без преобразования) код может быть следующий:
with THTTPSend.Create do begin if HTTPMethod('GET',Edit1.Text)then begin Document.Position:= ; SetLength(B,Document.Size); for i := to Document.Size - 1 do Document.Read(B[i],1); label4.Caption:=GetCharset(Headers); end; end; Label6.Caption:=IntToStr(Length(B))+' байт текста'; case ComboBox1.ItemIndex of :Memo1.Text:=StringOf(B); [...] end;
Запускаем приложение и видим: Как и ожидалось – вместо русских букв кракозябры. Преобразуем их с помощью классового метода TEncoding.Convert:
var astr: String; B: TBytes; [...] case ComboBox1.ItemIndex of :Memo1.Text:=StringOf(B); 1:begin B:=TEncoding.Convert(TEncoding.UTF8,TEncoding.GetEncoding(1251),B); astr:=StringOf(B); Memo1.Lines.Add(astr); end; [...] end;
Здесь следует отметить, что TEncoding.GetEncoding(1251) возвращает кодовую страницу кириллического текста. Если необходимо получить другую кодовую страницу, то можете либо воспользоваться классовыми свойствами TEncoding либо определить кодовую страницу как я, используя данные с MSDN о доступных в Windows кодовых страницах. Проверим, что получилось в итоге. Грузим ту же самую страницу: Как видите – кракозябры преобразовались в нормальный русский текст. Какие плюсы дает нам использование TEncoding? Думаю, что ответ вполне очевиден – у нас появляется под рукой инструмент, позволяющий перекодировать строки из любых кодировок в любые, т.е. фактически возможности работы с текстом ограничиваются количеством доступных в Windows кодовых страниц, а их по данным MSDN 152 штуки. Прикиньте сколько вариантов получится, если в Convert используется пара кодовых страниц. Много :). Но, наряду с таким большим и жирным плюсом существует и минус – TEncoding есть только в версиях Delphi 2009 и выше, что исключает его использование в более ранних версиях. Как быть? Если хотите получить не менее впечатляющие возможности работы с кодировками – используйте возможности MLang. Вот как раз и пример его использования.
3.2. Использование возможностей MLang для работы с кодовыми страницами
Позволю себе ещё раз напомнить, что скачать всё необходимое для реализации возможностей MLang Вы можете с этой страницы или, перейдя по этой ссылке. В архиве содержатся всего два модуля: MLang.pas и HtmlCPConvert.pas. Подключаем оба модуля к проекту и для получения читабельного текста пишем:
Memo1.Text:=RawHTMLToHTML(StringOf(B));
RawHTMLToHTML из модуля HtmlCPConvert переводит текст в кодировку windows-1251. Также есть и обратный метод для перевода текста в RawByteString и называется этот метод HTMLToRawHTML. Результат преобразования текста с помощью MLang абсолютно идентичен предыдущему варианту: Если Вам необходимо работать со множеством кодировок, как при использовании TEncoding, то придётся самостоятельно немного доработать модуль HtmlCPConvert. В целом возможности TEncoding и MLang вполне сопоставимы. И, наконец, третий вариант – использование методов модуля System.pas.
3.3. Использование методов System.pas для перекодирования текста
В модуле System.pas можно найти следующие полезные функции для работы с кодировками:
Utf8Encode(const US: UnicodeString): RawByteString; function UTF8EncodeToShortString(const WS: WideString): ShortString; function Utf8Decode(const S: RawByteString): WideString; function UTF8ToUnicodeString(const S: RawByteString): UnicodeString; function UTF8ToString(const S: RawByteString): string; function AnsiToUtf8(const S: string): RawByteString; function Utf8ToAnsi(const S: RawByteString): string;
Как видите, методы завязаны на работе с конкретными кодовыми страницами UTF-8, ANSI, а также на работе с новым типом данных RawByteString. Поэтому возможности третьего способы по сравнению с первыми двумя резко ограничены. Хотя в реалиях нынешнего Рунета их вполне достаточно, т.к. веб-страницы в кодировке koi8-r уже больше раритет, чем обыденность. Использовать методы достаточно просто. Например так:
var RS: RawByteString; [...] begin RS:=StringOf(B); Memo1.Text:=Utf8ToAnsi(RS); end;
Charsets
Часто в веб-программировании и вёрстке html-страниц приходится думать о кодировке редактируемого файла — ведь если кодировка выбрана неверная, то есть вероятность, что браузер не сможет автоматически её определить и в результате пользователь увидит т.н. «кракозябры».
Возможно, вы сами видели на некоторых сайтах вместо нормального текста непонятные символы и знаки вопроса. Всё это возникает тогда, когда кодировка html-страницы и кодировка самого файла этой страницы не совпадают.
Вообще, что такое кодировка текста? Это просто набор символов, по-английски «charset » (character set). Нужна она для того, чтобы текстовую информацию преобразовывать в биты данных и передавать, например, через Интернет.
Собственно, основные параметры, которыми различаются кодировки — это количество байтов и набор спец.символов, в которые преобразуется каждый символ исходного текста.
Краткая история кодировок:
Одной из первых для передачи цифровой информации стало появление кодировки ASCII — American Standard Code for Information Interchange — Американская стандартная кодировочная таблица, принятая Американским национальным институтом стандартов — American National Standards Institute (ANSI).
В этих аббревиатурах можно запутаться Для практики же важно понимать, что исходная кодировка создаваемых текстовых файлов может не поддерживать все символы некоторых алфавитов (к примеру, иероглифы), потому идёт тенденция к переходу к т.н. стандарту Юникод (Unicode), который поддерживает универсальные кодировки — Utf-8, Utf-16, Utf-32 и др.
Самая популярная из кодировок Юникода — кодировка Utf-8. Обычно в ней сейчас верстаются страницы сайтов и пишутся разные скрипты. Она позволяет без проблем отображать различные иероглифы, греческие буквы и прочие мыслимые и немыслимые символы (размер символа до 4-х байт). В частности, все файлы WordPress и Joomla пишутся именно в этой кодировке. А также некоторые веб-технологии (в частности, AJAX) способны нормально обрабатывать только символы utf-8.
Установка кодировок текстового файла при создании его обычным блокнотом. Кликабельно
В Рунете же ещё можно встретить сайты, написанные с расчётом на кодировку Windows-1251 (или cp-1251). Это специальная кодировка, предназначенная специально для кириллицы.
Почему вообще необходимо иметь представление о разных кодировках? Дело в том, что нередко на том же WordPress можно встретить, например, в Footer’е знаки вопроса вместо нормального текста. Это просто говорит о том, что php-файл Footer’а сохранён в одной кодировке, а в заголовке html-страницы указана совсем другая кодировка. Прочитайте — как сменить кодировку файла и что в этом поможет.
ли со статьей или есть что добавить?