Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Общие вопросы > Немецкая ОС, JAVA и кодировка |
Автор: sergejzr 5.2.2006, 14:19 | ||
Странности меня преследуют. По идее ява работает с UTF-8, ведь так? Я настроил всё под UTF-8 (test.java правильно в UTF-8, специально проверил) Теперэ по идее с кириллицей проблем быть не должно, думаю я. Но нижеприведённый код производит знаки вопроса и в файле и в консоли. Ну консоль, она немецкая, я в принципе и не ожидаю чудес, но ведь в файл должно писаться нормально? Вообщето следующей задачей бидет на сокет вывести UTF-8. Но сперва надо проблему с файлами решитэ. А она решаема! Еклипса ведь сохраняет test.java правильно в UTF-8. Какие будут соображения? Может еклипсу надо настроить как нибудь?
|
Автор: Nobody 5.2.2006, 14:44 |
Когда же все запомнят, что Reader/Writer надо создавать с явным указанием кодировки... LSD Может где-нибудь это большими буквами написать? |
Автор: LSD 5.2.2006, 14:49 | ||
К сожалению FileWriter-у нельзя указать кодировку, он использует системную. Можно только заменить на комбинацию OutputStreamWriter/FileOutputStream. В FAQ например. Возмешься за статью о кодировках? |
Автор: sergejzr 5.2.2006, 15:06 |
Отлично, в файл пишется! сейчас попробую на сокет, а пока может будут соображения насчёт консоли? |
Автор: LSD 5.2.2006, 15:31 |
Если речь идет о консоли винды, то: * в консоли выполняем ChCp 1251 и ставим шрифт Lucida Console * запускаем программу с ключем -Dfile.encoding=Cp1251 По идее должно сработать. |
Автор: sergejzr 6.2.2006, 00:54 |
Продолжение истории. Всё прекрасно получилось. Странихки генерятся, кодировка совпадает. Трабла с базой. База у меня на компе с русской ОС - Виндовс ХР Получаю строки в странной кодировке и раскодировать уже не могу. Пробовал разные извращения как например: "jdbc:mysql://mojcomp:3306/vpf?useUnicode=true&characterEncoding=UTF-8" Строки - кириллица. Мне надо чтобы он в UTF-8 забирал строки конечно. Может можно как то узнать или установить кодировку строк из базы? И как правильно перекодировать потом? |
Автор: LSD 6.2.2006, 10:37 | ||
Перекодировкой строк из кодировки СУБД в UTF-16 занимается драйвер, поэтому копать надо в его направлении. Какая кодировка использется в базе?
Ну для начала надо узнать, что за СУБД ![]() |
Автор: sergejzr 6.2.2006, 13:05 | ||
Это MySQL
Xex. Судя по тому, хто говорит конфигурация - UTF-8 Но там каракули. Причём на русской винде (где база стоит) отображается. Я сейчас страницу перегнал в 1251 взглянут´на безобразие можно (тол´ко сервер переодически включается): http://84.136.149.78:8080/forum/forumHandler |
Автор: Wowa 6.2.2006, 13:20 |
Попробуй первым делом после коннекта провести кверю: SET NAMES 'utf-8' Добавлено @ 13:20 http://dev.mysql.com/doc/refman/4.1/en/charset-connection.html Добавлено @ 13:23 Что является фактом, так это то, что в форумской базе(той, которую ты используешь также) неправильно прописан charset и Collation для таблица И столбцов в таблицах. Я не знаю, как так вышло - но это прописалось как-то автоматом неправильно. А менять вручную для каждого столбца более 50 таблиц, плюс у самих таблиц - у меня терпения не хватит. Может тут собака зарыта? |
Автор: sergejzr 6.2.2006, 13:36 | ||
А как можно вообще это поменять? ябы попробовал на одной таблице, посмотрел, что выйдет.. |
Автор: Wowa 6.2.2006, 13:40 | ||
http://dev.mysql.com/doc/refman/4.1/en/charset-table.html http://dev.mysql.com/doc/refman/4.1/en/charset-column.html Посмотри эти ссылки.. В одной из них: To change the character set (and collation) for all columns in an existing table, use... ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]; Лично у меня вызывает сомнение, что поменяется character set и collation всех столбцов. Я менял это черех пхпмайадмин и менялось только у таблицы, но НЕ у столбцов. |
Автор: sergejzr 6.2.2006, 13:41 |
Кстати если сеичас кодировку поставит´cp866 в браузере, тогда можно даже кое что прочитать. Но получается как будто ещё лишний байт там. |
Автор: Wowa 6.2.2006, 13:41 |
ALTER TABLE mytablename DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci Добавлено @ 13:42 Хотя вообще я согласен! В первом примере же используется CONVERT TO. Так, что столбцы тоже должны быть обработаны по идее. |
Автор: sergejzr 6.2.2006, 13:55 |
Хмм- никакой реакции. Кстати на странице там имена фроумов я конвертирую сейчас так name=new String(r.getString("name").getBytes("UTF-8"),"CP1251"); все остальные имена из базы просто копируются. Поэтому там знаки вопросов.. |
Автор: Wowa 6.2.2006, 14:02 |
А попробуй эту кверю первым делом: SET NAMES 'windows-1251' |
Автор: LSD 6.2.2006, 14:27 | ||||
Покурив немного http://dev.mysql.com/doc/refman/4.1/en/cj-configuration-properties.html мануал, я решил что надо попробовать такой URL:
или такой:
(так и не понял назначение параметра useUnicode) |
Автор: sergejzr 6.2.2006, 14:46 |
LSD, пробовал... Добавлено @ 14:48 Без изменений. Блин, ну не руками же перекодировать... |
Автор: Wowa 6.2.2006, 15:30 |
sergej.z какая версия мускула стоит? А что если создать заново базу и таблицу в кодировке windows-1251, записать туда мусор, а затем попробовать явой их получить? |
Автор: sergejzr 6.2.2006, 16:21 |
Я могу выписать таблицу букв - чисел может по ним кодировку определить? |
Автор: LSD 6.2.2006, 16:44 |
Если записать строку в базу, а потом ее считать, то все впорядке с кодировкой? |
Автор: Wowa 6.2.2006, 16:48 |
Я дума., что кодировку определять не стоит. Т.к. это не кодировка, а просто поломанный текст. Где-то НЕ с той кодировки происходит конвертацию в другую. В результате - абра-кадабра. P.S. Кстати, ява использует utf-8 или utf-16? |
Автор: LSD 6.2.2006, 16:49 |
Внутри class-файлов UTF-8, внутри JVM - UTF-16. |
Автор: sergejzr 6.2.2006, 16:51 |
Вот такая.. А= -64 Б= -63 В= -62 Г= -61 Д= -60 Е= -59 Е= -88 Ж= -58 З= -57 И= -56 Й= -55 К= -54 Л= -53 М= -52 Н= -51 О= -50 П= -49 Р= -48 С= -47 Т= -46 У= -45 Ф= -44 Х= -43 Ц= -42 Ч= -41 Ш= -40 Щ= -39 ъ= -38 Ы= -37 ь= -36 Э= -35 Ю= -34 Я= -33 а= -32 б= -31 в= -30 г= -29 д= -28 е= -27 ё= -72 ж= -26 з= -25 и= -24 й= -23 к= -22 л= -21 м= -20 н= -19 о= -18 п= -17 р= -16 с= -15 т= -14 у= -13 ф= -12 х= -11 ц= -10 ч= -9 ш= -8 щ= -7 ъ= -6 ы= -5 ь= -4 э= -3 ю= -2 я= -1 Добавлено @ 17:02 Если пишу в базу - вопросы забиваются. надо попробовать в различных кодировках... |
Автор: LSD 6.2.2006, 17:04 |
Это windows-1251. |
Автор: sergejzr 6.2.2006, 18:47 |
Как бы я хотел, цчтобы йето так было. Почему тогда кракозяблы? Сейчас насильственно перекодировал по таблице байт за байтом - стало нормально. Но это не выход.. Попробую обе таблицы вывести из базы и из программы. Посмотрим на отличия... |
Автор: sergejzr 6.2.2006, 19:17 | ||
Хммм.. пишу незатейливый код:
Прикол в том, что после перекодировки получаются байты со знаками вопроса, но в браузере отображается строка нормально. А до кодировки распечатывается таблица, а в браузере - каракули. |
Автор: LSD 6.2.2006, 20:40 | ||
Как я понял в строке содержится последовательно все буквы русского алфавита, да? Выведи на печать такую штуку:
|
Автор: sergejzr 6.2.2006, 21:01 | ||
Я добавил пробелы между отдельными буквами и распечатал ещё раз само слово результат: http://84.136.173.123:8080/forum/forumHandler
Добавлено @ 21:04 Результат можно интерпретировать. как то, что кодировка самого исходника не 1251, верно? но ведь она такая. или я чегото не понимаю совсем... Какая она тогда?.. Правда выводя на soket я пишу кодировку stream'у 1251 ещё раз Добавлено @ 21:06 Там если что маленькое несоответсвие в базе Ъ, Ь большими, а в коде маленькими остальное один к одному |
Автор: sergejzr 6.2.2006, 21:28 |
Вот! проблема обрисовалась!!!! Я убрал setCharacterEncoding из response. Теперь строки напрямую из базы пмшуться на сокет. Отображается правильно. Осталась только трабла со строками редактора. Как мне их тут в эклипсе сразу в 1251 писать? Вроде выставлено всё как надо в Preferences. А он как видишь чтото странное делает с ними.. В любом случае - спасибо огромное. Это уже хороший толчёк!. Добавлено @ 21:34 Вот, что он выдаёт мне из твоего кода Russian alphabet 410 411 412 413 414 415 415 416 417 418 419 41a 41b 41c 41d 41e 41f 420 421 422 423 424 425 426 427 428 429 44a 42b 44c 42d 42e 42f 430 431 432 433 434 435 451 436 437 438 439 43a 43b 43c 43d 43e 43f 440 441 442 443 444 445 446 447 448 449 44a 44b 44c 44d 44e 44f ?????????????????????????????????????????????????????????????????? Russian alphabet in windows-1251 c0 c1 c2 c3 c4 c5 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 fa db fc dd de df e0 e1 e2 e3 e4 e5 b8 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff АБВГДЕЕЖЗИЙКЛМНОПРСТУФХЦЧШЩъЫьЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя Russian alphabet in database c0 c1 c2 c3 c4 c5 a8 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 b8 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя Хотя кодировка файла стоит CP1251, по всей видимости она не 1251. Бяка какая то.. Добавлено @ 21:38 Kaзчется я понимаю... Исходник всегда компилится в УТФ-8, верно? и перекодировать соответственно всегда надо руками. Просто выдать строку на сокет не получится. Правильно? |
Автор: LSD 6.2.2006, 21:53 | ||||||
К сожалению нет (вернее скорее всего в БД то, кодировка 1251). Первая строка это коды русского алфавита в кодировке UTF-16. Вторая это коды русского алфавита в кодировке windows-1251. А вот третья это коды русского алфавита неправильно преобразованного в UTF-16. При преобразовании байт из windows-1251 C0 заменяется на 410, C1 на 411, и т.д. А здесь коды не были корректно преобразованы, просто лепили как есть и все. Такое може происходить если перекодировать из ISO-8859-1. Вот примерчик где этот эффект демонстрируется преобразование кодировок (попробуй кодировки US-ASCII и windows-1251):
Преобразовать конечно данные не составит труда:
Можно попробовать получить "сырое" значение через resultSet.getBytes("column"). P.S. Скачал себе MySQL, попробую с ним поиграться. Добавлено @ 21:58 Нет, должна быть настройка которая определяет кодировку исходника. Для javac это параметр -encoding, у эклипсы не знаю. Вообщем я не понял, что ты сделал. Но если русская А прописанная в виде литерала, имеет код 410, значит для исходника используется правильная кодировка. |
Автор: sergejzr 6.2.2006, 23:25 | ||
Итак, подведём итоги. Если выписывать строки из БД напрямую на сокет - кодировка CP1251 совпадает и всё отображается корректно. Это очень хорошо. В тоже время русские литералы исходника (который тоже в CP1251) превращаются в знаки вопроса.
Значит по теории у меня всё правильно. Но это означает, что все русские литералы перед выводом на сокет надо конвертить, ведь верно отображается именно А - с0 В принципе конечно хотелось бы обойтись совсем без конвертации, но если это невозможно, то надо определится (мне) или базу конвертить под исходник или исходник под базу. По большому счёту это не играет роли, потому что загрузка строк в мозги будет проведена только один раз при инициализации. С другой стороны не хочется следить за каждой константой в исходнике. Короче говоря, хотелось бы обойтись совсем без конвертации. Чтобы кодировка файла и строк совпадала. Это означает, что файл надо в другую кодировку перенести, но в какую???? Если 1251 не работает.. |
Автор: LSD 7.2.2006, 12:14 | ||
Исходник сохраняй в windows-1251, а при компиляции указывай что он ISO-8859-1. Но это все полумеры, которые могут потом боком выйти. По хорошему надо привести базу в норму. Либо разобраться почему у нас не работает русский язык (кстати а что с другими языками?), но тут похоже сделали все что смогли. Либо пересоздать базу и сделать export/import. |
Автор: Nobody 7.2.2006, 13:37 |
sergej.z Переделай всё в UTF-8 и не извращайся. |
Автор: Wowa 7.2.2006, 13:39 |
речь идет о базе этого форума. Я думаю, что если все сообщения станут в utf-8. Тем самым начнут почти в два раза больше места занимать - никто не обрадуется. Т.к. у многих еще модемы. Да и база форума, которая сейчас весит около 400Мб, станет весит наверное 600-700Мб. |
Автор: sergejzr 7.2.2006, 13:50 | ||
Ну так вес страницы ведь увеличится для юзеров. Поэтому извращатся и приходится.
Так как всё равно транслятор надо делать, все киррилические строки будут в двух местах хранится. В базе и трансляторе. В принципе не сложно их в трансляторе один раз при старте перекодировать. Проблема только с ХТМЛ комментами, прописанными в строках, но тут можно траблу обойти разделив на ХМЛ и ХСЛ. И ХСЛ из файла читать, он ведь тогда сразу будет в правильной кодировке. Думаю - это оптимальное решение ![]() ![]() Всем спасибо! |
Автор: LSD 7.2.2006, 15:12 | ||||
Я не об этом. Я говорю о том, у нас внутри Java приложения есть строка в которой содержится обракадабра. Например символы \u00D7 и \u00F7 выдают Character.isLetter() - false (это русская Ч). Ни в верхний ни в нижний регистр ее перевести нельзя, регулярные выражение которые используют шаблон \w будут на ней спотыкаться и еще неизвестно какие баги вылезут. Поэтому нам важно получить в Java приложение строку в нормальной кодировке. А уже пользователю можно выдавать и windows-1251 и UTF-8 как захотим. И в базе можем хранить тоже как нам удобно, главное чтоб могли правильно прочитать. |
Автор: sergejzr 7.2.2006, 15:36 | ||
Ну это не страшно. Из кириллицы в исходниках только надписи. Обрабатывать нам их не надо просто на сокет выдавать как есть. Перекодировать каждый раз на выходе - лишняя трата ресурсов. Тем более, что из транслятора мы можем по надобности эту строку в любой кодировке запросить. |
Автор: LSD 9.2.2006, 00:21 | ||||
Я говорил о строках получаемых из базы, их-то обрабатывать придется. Не такая уж и большая. Я накидал тестик:
Прогнав его на файле в 1Мб (перегонял из Cp866 в Cp1251) получил такие результаты:
Заглавная страница винграда 150Кб, в ней большая часть текста идет латиницей, и преобразовывать надо будет только в одну сторону. Так что преобразование будет потреблять около 5мсек. Добавлено @ 00:23 P.S. Вот что по этому поводу думает Sun: http://java.sun.com/developer/technicalArticles/Intl/HTTPCharset/. |
Автор: vinegr 9.2.2006, 19:00 |
извините, если это уже сказали до меня - но есть прекрасный мануал "JAVA -русские буквы и не только" (в инете сотня копий, ищется слету) берете и осмысливаете с заменой "русскости" на "немецкость" ![]() |