Некоторые проблемы настолько сложны, что нужно быть очень умным и очень хорошо информированным, чтобы не быть уверенным в их решении. |
Лоренс Дж. Питер Peter's Almanac |
//Данные в кодировке КОИ-8
byte[] koi8Data=...;
//Преобразуем из КОИ-8 в Unicode
String string=new String(koi8Data,"KOI8_R");
//Преобразуем из Unicode в Windows-1251
byte[] winData=string.getBytes("Cp1251");
Список 8-ми битовых кодировок, доступных в современных JDK и поддерживающих русские буквы Вы можете найти ниже, в разделе "8-ми битовые кодировки русских букв".
//Строка Unicode
String string="...";
//Преобразуем из Unicode в UnicodeLittleUnmarked
byte[] data=string.getBytes("UnicodeLittleUnmarked");
При подобных преобразованиях легко ошибиться - если кодировка байтовых данных не соответствуют указанному параметру при преобразовании из byte в char, то перекодирование будет выполнено неправильно.
Иногда после этого можно вытащить правильные символы, но чаще всего часть данных будет безвозвратно потеряна.
InputStream is=...;
int b;
StringBuffer sb=new StringBuffer();
while((b=is.read())!=-1){
sb.append((char)b); // так делать нельзя
}
String s=sb.toString();
Обратите внимание на приведение типа - "(char)b".
Значения байтов вместо перекодирования просто скопируются в char (диапазон значений 0-0xFF, а не тот, где находится кириллица).
Такому копированию соответствует кодировка ISO-8859-1 (которая один в один соответствует первым 256 значениям Unicode), а значит, можно считать, что этот код просто использует её (вместо той, в которой реально закодированы символы в оригинальных данных).
Если Вы попытаетесь отобразить полученное значение - на экране будут или вопросики или кракозяблы.
Например, при чтении строки "АБВ" в виндовой кодировке может запросто отобразиться что-то вроде такого: ""ÀÁÂ".
Подобного рода код часто пишут программисты на западе - с английскими буквами работает, и ладно.
Исправить такой код легко - надо просто заменить StringBuffer на ByteArrayOutputStream:
InputStream is=...;
int b;
ByteArrayOutputStream baos=new ByteArrayOutputStream();
while((b=is.read())!=-1){
baos.write(b);
}
//Перекодирование байтов в строку с использованием
//кодировки по умолчанию
String s=baos.toString();
//Если нужна конкретная кодировка - просто укажите
//её при вызове toString():
//
//s=baos.toString("Cp1251");
Более подробно о распространённых ошибках смотрите раздел "Типичные ошибки".