Кодирование/набор символов Java InputStream

Выполнение следующего (пример) код

import java.io.*;

public class test {
    public static void main(String[] args) throws Exception {
        byte[] buf = {-27};
        InputStream is = new ByteArrayInputStream(buf);
        BufferedReader r = new BufferedReader(
                new InputStreamReader(is, "ISO-8859-1"));
        String s = r.readLine();
        System.out.println("test.java:9 [byte] (char)" + (char)s.getBytes()[0] + 
                " (int)" + (int)s.getBytes()[0]);
        System.out.println("test.java:10 [char] (char)" + (char)s.charAt(0) + 
                " (int)" + (int)s.charAt(0));
        System.out.println("test.java:11 string below");
        System.out.println(s);
        System.out.println("test.java:13 string above");
    }
}

дает мне этот вывод

test.java:9 [byte] (char)? (int)63
test.java:10 [char] (char)? (int)229
test.java:11 string below
?
test.java:13 string above

Как я сохраняю корректное значение байта (-27) в строке 9 распечаток? И, следовательно, получите ожидаемый вывод System.out.println(s) команда (Ж).

14
задан Stephen C 15 June 2010 в 09:19
поделиться

2 ответа

Если вы хотите сохранить байтовые значения, в идеале не используйте Reader вообще. Чтобы представить произвольные двоичные данные в виде текста и позже преобразовать их обратно в двоичные данные, следует использовать кодировку base16 или base64.

Однако, чтобы объяснить, что происходит, когда вы вызываете s.getBytes(), используется кодировка по умолчанию, которая, очевидно, не включает символ Юникода U+00E5.

Если вы вызовете s.getBytes("ISO-8859-1") везде вместо s.getBytes(), я подозреваю, что вы вернете правильное значение байта... но полагаться на ISO-8859-1 для этого довольно грязно IMO.

22
ответ дан 1 December 2019 в 09:00
поделиться

Как отмечалось, getBytes() (без аргументов) использует кодировку платформы Java по умолчанию, которая может быть не ISO-8859-1. Простая печать должна сработать, если ваш терминал и кодировка по умолчанию совпадают и поддерживают этот символ. Например, в моей системе терминал и кодировка Java по умолчанию - UTF-8. Тот факт, что вы видите символ '?', указывает на то, что ваши кодировки не совпадают или å не поддерживается.

Если вы хотите вручную перекодировать в UTF-8 в вашей системе, сделайте следующее:

String s = r.readLine();
byte[] utf8Bytes = s.getBytes("UTF-8");

Это должно дать массив байтов с {-61, -91}.

8
ответ дан 1 December 2019 в 09:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: