Java: проблема многоплатформенного кодирования строк - PullRequest
2 голосов
/ 12 ноября 2010

У меня странная ситуация, с которой я не разобрался, как справиться. У нас есть разработчики, работающие на нескольких платформах, основной платформой является linux, но у нас также есть люди, работающие на OS X и Windows.

У нас есть набор тестов, которые все прекрасно работают и работают в Linux. Но когда мы пытаемся запустить их на OS X, они терпят неудачу. Неудачное утверждение - проверка того, что две строки равны, но есть один символ, который в среде Mac не выглядит одинаково. Я совершенно уверен, что это просто потому, что файл кодируется определенным образом, а ожидаемое строковое значение, которое жестко закодировано, кодируется по-разному. Мне удалось исправить некоторые другие проблемы с кодировкой, установив файл JVM.encoding с помощью MAVEN-OPTS, но до этого момента я был озадачен этой проблемой.

Структура выглядит примерно так: some.xml -> xslt -> object assertEquals («ожидаемое значение», object.valueToTest ());

Есть какие-нибудь идеи о том, как исправить это несоответствие? Или даже почему это происходит в первую очередь?

Заголовок файла xml говорит, что он закодирован в UTF-8, но возможно, что файл может быть закодирован по-разному в файловой системе. Есть ли способ для меня, чтобы проверить, что фактическая кодировка?

Ответы [ 4 ]

1 голос
/ 12 ноября 2010

Если файл XML начинается с <?xml ... encoding="UTF-8"?>, то вы можете быть достаточно уверены, что в файловой системе он закодирован как UTF-8. В противном случае откройте его в редакторе, который позволит вам увидеть, что такое необработанные байты, например, emacs М-х find-file-literally.

Кроме того, ваш исходный код Java может содержать забавный байт в строковом литерале, который по-разному представлен в разных кодировках. Я думаю, что компилятор читает исходный код, используя кодировку платформы по умолчанию. Чтобы обойти эту проблему переносимости, вы можете закодировать любой не-ascii символ, используя обозначение \ uxxxx. Это хорошо для пользователей английского языка, но может быть немного утомительным для всех остальных!

EDIT : не по теме, но это напомнило мне любопытный файл, который я нашел на работе в тестовом примере. Это был XML-файл, который был закодирован как ascii / utf-8, но тег кодирования сказал «UTF-16». Это выглядело бы нормально в простых редакторах, таких как блокнот, которые не учитывали директиву кодирования XML, но выглядело бы странно в интеллектуальных редакторах, которые считывали файл как UTF-16

1 голос
/ 12 ноября 2010

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

Как символ представлен в файле? Вы можете попытаться экранировать любой юникод в строковых константах, используя \ uXXXX нотацию .

Эта страница также предоставляет другую подсказку относительно того, почему это может не работать. Кодировка по умолчанию на Mac - «MacRoman», который не является подмножеством UTF-8. Поэтому, как вы и подозревали, персонаж, скорее всего, интерпретируется по-разному.

1 голос
/ 12 ноября 2010

В основном, , что сказал Пит Киркхам .

Мне удалось исправить некоторые другие проблемы с кодированием, настроив JVM file.encoding через MAVEN-OPTS

Не делай этого; он не поддерживается и может иметь непредвиденные побочные эффекты .

Правильный способ указать кодировку исходного файла в файлах pom.xml.

<project>
  ...
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  ...
</project>

Это гарантирует, что компилятор будет последовательно декодировать исходные файлы на всех платформах и эквивалентно использованию javac -encoding X ...

Подробнее о кодировании в исходных файлах здесь .

1 голос
/ 12 ноября 2010

Обычная причина, по которой это происходит, заключается в том, что кто-то использует одно преобразование байтов старой строки <->, которое не принимает параметр для указания кодировки.

Не исключено, что это проблема кодирования в исходном файле, хотя я перешел только между Windows и Linux, поэтому никогда не видел его, но вы должны использовать экранирование Unicode для любой кодовой точки выше U00007f.

...