2011-12-22 2 views
4

Общей ошибкой при написании кода, который читает текст из потока в Java, является забывание указать кодировку. Если вы ничего не укажете, Java будет использовать кодировку по умолчанию для платформы, которая в конечном итоге вызывает проблемы («Но это работает на моем компьютере!»).Какую кодировку использовать для поиска кода, который использует кодировку по умолчанию?

Чтобы найти эти проблемы, я хочу использовать необычную по умолчанию кодировку, которая должна прерывать как можно больше операций ввода-вывода. Идея состоит в том, что по крайней мере любой персонаж вне ASCII будет искажен.

В большинстве наших документов используется кодировка UTF-8. ISO-8859-1 может работать, потому что он просто сохраняет вход (это сопоставление 1: 1 между байтами и символами). Любые умляуты будут считывать последовательности с двумя/древовидными байтами. Но мне интересно, можем ли мы сделать лучше.

Какую кодировку вы предлагаете использовать с list of supported encodings?

+0

EBCDIC - это весело, если у вашей JVM есть некоторые. http://en.wikipedia.org/wiki/Extended_Binary_Coded_Decimal_Interchange_Code – Mat

+0

У меня есть EBCDIC (Cp037 на Java), но когда я использую эту кодировку, я больше не могу запускать Maven, потому что он пытается создавать процессы с использованием закодированных строк EBCDIC ...; -) –

ответ

1

Я думаю, что любой из 16 или 32-битных UTF даст вам много «нулевых» символов, которые должны сломать много строк. Кроме того, использование одного с BOM (маркер байтового байта) должно «разбить» файл.

Но я бы предположил, что есть инструменты анализа кода, которые могут проверять создание Строков, Читателей и Писателей без кодировки.

Edit: FindBugs, кажется, чтобы быть в состоянии сделать это: Dm: Reliance on default encoding (DM_DEFAULT_ENCODING)

2

По умолчанию кодировка UTF-16 имеет хорошие шансы «манипулировать» любым документом, который не является UTF-16.

Но я думаю, вы идете об этом неправильно. Лучший способ обнаружить изворотливый код, который опирается на кодировки по умолчанию, - написать некоторые пользовательские правила для чего-то вроде PMD. Просто найдите код, который использует методы и конструкторы-нарушители на String, классы ввода-вывода и так далее.

(Проблема с подходом «использовать странную кодировку по умолчанию» является то, что ваше тестирование не может быть достаточно, чтобы осуществлять весь код обижая, или он может осуществлять код, но не обнаруживает коверкая.)

+0

UTF-16 имеет ту же проблему, что и EBCDIC (Cp037): ProcessBuilder внезапно не может запускать процессы :-(Кажется, он использует кодировку по умолчанию: -/Но +1 для подхода PMD. –

1

java.nio.charset.Charset имеет метод, который возвращает newDecoder()Decoder. У Deconder есть методы isAutoDetecting(), isChasetDetected() и detectedCharset(), которые кажутся полезными для вашей задачи. К сожалению, все эти методы являются необязательными.

Я думаю, что вы должны взять все доступные Charsets (Charset.availableCharsets()) и сначала проверить, не являются ли они автоопределяемыми. Таким образом, когда вы получаете новый поток, сначала попробуйте использовать встроенный механизм автоопределения для тех кодировок, которые реализуют эти дополнительные операции.

Если ни один из этих декодеров не может обнаружить механизм, вы должны попытаться декодировать поток (как вы объяснили), пытаясь применить другие кодировки. Чтобы оптимизировать процесс, попробуйте отсортировать кодировки, используя следующие критерии.

Национальные алфавиты в первую очередь. Например, попробуйте кириллические кодировки перед тем, что касается латинских алфавитов.

Среди национальных алфавитов есть один, у которого больше персонажей. Например, японцы и китайцы будут в начале очереди.

Причиной такой стратегии является то, что вы хотите сбой как можно быстрее.Если ваш текст не содержит японских символов, вы должны проверить первый символ из своего потока, чтобы понять, что это не Японский. Но если вы попытаетесь использовать кодировку ASCII для декодирования французского текста, вам, вероятно, придется прочитать много символов, прежде чем вы увидите первый è.

Смежные вопросы