10 января 2012 г.

java и чтение unicode BOM

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

Баг на сане был открыт ещё в 2001 году, на данный момент помечен как «исправляться не будет», с объяснением «иначе некоторый софт может сломаться», т.е. баги тоже должны быть обратно совместимы ;) В каментах к багу много негодований, но обсуждение правильности этого решения пусть останется за рамками этой заметки.

На данный момент (конец jdk6 - начало jdk7) ошибка не исправлена и исправляться не собирается.

В качестве решения предлагается обрабатывать BOM-ы самостоятельно в коде. Готовые классы-обёртки находятся здесь: http://koti.mbnet.fi/akini/java/unicodereader/.

Например, UnicodeReader оттуда работает как замена InputStreamReader в такой конструкции:
new InputStreamReader( new FileInputStream( new File( "config.txt" ) ), "UTF-8" )
и является просто обёрткой над ним, создавая InputStreamReader внутри себя с кодировкой согласно прочитанным BOM из файла, либо указанной в конструкторе (как и в конструкторе InputStreamReader) конкретной дефолтной кодировке.