Как я могу конвертировать между ISO-8859-1 и UTF-8 в Java? - PullRequest
62 голосов
/ 17 марта 2009

Кто-нибудь знает, как преобразовать строку из ISO-8859-1 в UTF-8 и обратно в Java?

Я получаю строку из Интернета и сохраняю ее в RMS (J2ME), но я хочу сохранить специальные символы и получить строку из RMS, но с кодировкой ISO-8859-1. Как мне это сделать?

Ответы [ 7 ]

92 голосов
/ 17 марта 2009

В общем, вы не можете этого сделать. UTF-8 способен кодировать любую кодовую точку Unicode. ISO-8859-1 может обрабатывать лишь малую часть из них. Таким образом, перекодировка из ISO-8859-1 в UTF-8 не является проблемой. Переход назад от UTF-8 к ISO-8859-1 приведет к появлению в тексте «заменяющих символов» (& # xFFFD;) при обнаружении неподдерживаемых символов.

Для перекодировки текста:

byte[] latin1 = ...
byte[] utf8 = new String(latin1, "ISO-8859-1").getBytes("UTF-8");

или

byte[] utf8 = ...
byte[] latin1 = new String(utf8, "UTF-8").getBytes("ISO-8859-1");

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

8 голосов
/ 12 августа 2016

Что сработало у меня: («üzüm bağları» - правильный текст на турецком)

Преобразование ISO-8859-1 в UTF-8:

String encodedWithISO88591 = "üzüm baÄları";
String decodedToUTF8 = new String(encodedWithISO88591.getBytes("ISO-8859-1"), "UTF-8");
//Result, decodedToUTF8 --> "üzüm bağları"

Преобразование UTF-8 в ISO-8859-1

String encodedWithUTF8 = "üzüm bağları";
String decodedToISO88591 = new String(encodedWithUTF8.getBytes("UTF-8"), "ISO-8859-1");
//Result, decodedToISO88591 --> "üzüm baÄları"
6 голосов
/ 17 марта 2009

Если у вас есть String, вы можете сделать это:

String s = "test";
try {
    s.getBytes("UTF-8");
} catch(UnsupportedEncodingException uee) {
    uee.printStackTrace();
}

Если у вас «сломанный» String, вы сделали что-то не так, преобразование String в String в другой кодировке определенно не подходит! Вы можете преобразовать String в byte[] и наоборот (с учетом кодировки). В Java String с AFAIK кодируются UTF-16, но это детали реализации.

Скажем, у вас есть InputStream, вы можете прочитать в byte[] и затем преобразовать его в String, используя

byte[] bs = ...;
String s;
try {
    s = new String(bs, encoding);
} catch(UnsupportedEncodingException uee) {
    uee.printStackTrace();
}

или даже лучше (благодаря Эриксону) используйте InputStreamReader вот так:

InputStreamReader isr;
try {
     isr = new InputStreamReader(inputStream, encoding);
} catch(UnsupportedEncodingException uee) {
    uee.printStackTrace();
}
3 голосов
/ 13 июня 2016

Вот простой способ вывода строки (я создал метод для этого):

public static String (String input){
    String output = "";
    try {
        /* From ISO-8859-1 to UTF-8 */
        output = new String(input.getBytes("ISO-8859-1"), "UTF-8");
        /* From UTF-8 to ISO-8859-1 */
        output = new String(input.getBytes("UTF-8"), "ISO-8859-1");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return output;
}
// Example
input = "Música";
output = "Música";
1 голос
/ 21 ноября 2018

Regex также может быть хорошим и эффективно использоваться (заменяет все символы UTF-8, не охваченные в ISO-8859-1 пробелом):

String input = "€Tes¶ti©ng [§] al€l o€f i¶t _ - À ÆÑ with some 9umbers as"
            + " w2921**#$%!@# well Ü, or ü, is a chaŒracte⚽";
String output = input.replaceAll("[^\\u0020-\\u007e\\u00a0-\\u00ff]", " ");
System.out.println("Input = " + input);
System.out.println("Output = " + output);
0 голосов
/ 30 октября 2018

Вот функция для преобразования UNICODE (ISO_8859_1) в UTF-8

public static String String_ISO_8859_1To_UTF_8(String strISO_8859_1) {
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < strISO_8859_1.length(); i++) {
  final char ch = strISO_8859_1.charAt(i);
  if (ch <= 127) 
  {
      stringBuilder.append(ch);
  }
  else 
  {
      stringBuilder.append(String.format("%02x", (int)ch));
  }
}
String s = stringBuilder.toString();
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
    data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                         + Character.digit(s.charAt(i+1), 16));
}
String strUTF_8 =new String(data, StandardCharsets.UTF_8);
return strUTF_8;
}

TEST

String strA_ISO_8859_1_i = new String("الغلاف".getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

System.out.println("ISO_8859_1 strA est = "+ strA_ISO_8859_1_i + "\n String_ISO_8859_1To_UTF_8 = " + String_ISO_8859_1To_UTF_8(strA_ISO_8859_1_i));

РЕЗУЛЬТАТ

ISO_8859_1 strA est = اÙغÙا٠String_ISO_8859_1To_UTF_8 = الغلاف

0 голосов
/ 06 апреля 2017

Apache Commons IO Класс Charsets может пригодиться:

String utf8String = new String(org.apache.commons.io.Charsets.ISO_8859_1.encode(latinString).array())
...