2009-04-07 2 views
0

Я написал небольшое приложение, которое выполняет некоторые манипуляции с текстом и записывает вывод в файл (html, csv, docx, xml), и все это прекрасно работает в Mac OS X. На окнах однако я, похоже, получаю проблемы кодирования символов, и многие из них «исчезают» и заменяются каким-то странным материалом. Обычно закрытие «» из пары.Ошибка кодирования символов - Java

Я использую FreeMarker для создания своих выходных файлов, и есть массив byte [], а в одном случае также ByteArrayStream между чтением шаблонов и записью вывода. Я предполагаю, что это проблема кодирования символов, поэтому, если кто-то может дать мне совет или указать мне какой-то ресурс «Лучшая практика» для работы с кодировкой символов в java.

Благодаря

ответ

5

Там действительно только одна лучшая практика: быть в курсе, что строки и байты две принципиально разные вещи, и что всякий раз, когда вы конвертировать между ними, вы используют кодировку символов (неявно или явно), на которую вы должны обратить внимание.

Типичные проблемные места в Java API, являются:

  • new String(byte[])
  • String.getBytes()
  • FileReader, FileWriter

Все они неявно используют кодировку платформы по умолчанию, которая зависит от операционной системы и пользовательские настройки локали. Как правило, рекомендуется избегать этого и явно объявлять кодировку в вышеуказанных случаях (к сожалению, FileReader/Writer не разрешает, поэтому вам нужно использовать InputStreamReader/Writer).

Однако ваши проблемы с кавычками и использование механизма шаблонов могут иметь гораздо более простое объяснение. Какую программу вы используете для написания своих шаблонов? Похоже, что он вставляет "smart quotes", которые являются частью кодировки cp1251 для Windows, но не существуют в более глобальной кодировке ISO-8859-1.

Возможно, вам необходимо знать, какая кодировка ваших шаблонов сохранена, и настроить механизм шаблонов для использования этой кодировки при чтении в шаблонах. Также имейте в виду, что некоторые файлы texxt, в частности XML, явно объявляют кодировку в заголовке, и если этот заголовок не согласуется с фактической кодировкой, используемой файлом, вы всегда будете сталкиваться с проблемами.

+0

Я использую FreeMarker, и объект Template, который я создаю, кажется, использует CP1251, хотя он также в другом поле утверждает, что использует UTF-8. И они выглядят как умные кавычки, но «» не исходит из моего tempalte, а из текста, который я обрабатываю как вход. – willcodejavaforfood

+0

Тогда проблема, похоже, и в конфигурации FreeMarker (противоречивые кодировки всегда очень плохие новости) и в вашем синтаксическом коде –

+0

Я определил UTF-8 в моих файлах xml и html. После использования свойства vm объект шаблона больше не показывает противоречивые кодировки. – willcodejavaforfood

3

Вы можете контролировать процесс кодирования JVM будет работать с путем подачи п, бывший

-Dfile.encoding = UTF-8

для (UTF-8, конечно) как аргумент JVM. Затем вы должны получать прогнозируемые результаты на всех платформах. Пример:

Java -Dfile.encoding = UTF-8 my.MainClass

+0

Это уверены ли исправить все, cheers mate – willcodejavaforfood

+0

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

1

Запуск JVM со стандартным кодированием через запутанное имя -Dfile.encoding позволит решить множество проблем.

Убедитесь, что ваше приложение не использует byte[] <-> String. Конверсии без указанной кодировки важны, поскольку иногда вы не можете принудительно применять кодировку VM (например,если у вас есть сервер приложений, используемый несколькими приложениями)

Если вы смущены всей проблемой кодирования или хотите пересмотреть свои знания, Joel Spolsky написал об этом great article.

0

я должен был убедиться, что OutputStreamWriter использует правильную кодировку

OutputStream out = ... 
OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8"); 
template.process(model, writer); 

Плюс, если вы используете ByteArrayOutputStream также убедитесь, что для вызова ToString с правильной кодировкой:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
... 
baos.toString("UTF-8"); 
Смежные вопросы