Почему кодировка US-ASCII принимает символы, отличные от US-ASCII? - PullRequest
3 голосов
/ 03 февраля 2011

Рассмотрим следующий код:

public class ReadingTest {

    public void readAndPrint(String usingEncoding) throws Exception {
        ByteArrayInputStream bais = new ByteArrayInputStream(new byte[]{(byte) 0xC2, (byte) 0xB5}); // 'micro' sign UTF-8 representation
        InputStreamReader isr = new InputStreamReader(bais, usingEncoding);
        char[] cbuf = new char[2];
        isr.read(cbuf);
        System.out.println(cbuf[0]+" "+(int) cbuf[0]);
    }

    public static void main(String[] argv) throws Exception {
        ReadingTest w = new ReadingTest();
        w.readAndPrint("UTF-8");
        w.readAndPrint("US-ASCII");
    }
}

Наблюдаемый вывод:

µ 181
? 65533

Почему успешен второй вызов readAndPrint() (тот, который использует US-ASCII)?Я ожидаю, что он выдаст ошибку, так как ввод не является правильным символом в этой кодировке.Какое место в Java API или JLS предписывает такое поведение?

Ответы [ 2 ]

9 голосов
/ 03 февраля 2011

Операция по умолчанию при поиске недекодируемых байтов во входном потоке заключается в замене их символом Unicode U + FFFD REPLACEMENT CHARACTER .

Если вы хотите изменить это, вы можете передать CharacterDecoder в InputStreamReader, для которого настроен другой CodingErrorAction:

CharsetDecoder decoder = Charset.forName(usingEncoding).newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
InputStreamReader isr = new InputStreamReader(bais, decoder);
3 голосов
/ 03 февраля 2011

Я бы сказал, что это то же самое, что и для конструктора String(byte bytes[], int offset, int length, Charset charset):

Этот метод всегда заменяет последовательности символов malformed-input и unmappable-символ на строку замены этого набора символов по умолчанию.Класс java.nio.charset.CharsetDecoder должен использоваться, когда требуется больший контроль над процессом декодирования.

Используя CharsetDecoder, вы можете указать другой CodingErrorAction.

...