3

次のコードを検討してください。

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 を使用する)の 2 番目の呼び出しが成功するのはなぜですか? このエンコーディングでは入力が適切な文字ではないため、エラーがスローされると予想されます。この動作を義務付ける Java API または JLS の場所はどこですか?

4

2 に答える 2

9

入力ストリームでデコードできないバイトを見つけるときのデフォルトの操作は、それらをUnicode文字U + FFFDREPLACEMENTCHARACTERに置き換えることです。

これを変更したい場合は、別の構成になっているにを渡すことができます。CharacterDecoder InputStreamReaderCodingErrorAction

CharsetDecoder decoder = Charset.forName(usingEncoding).newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
InputStreamReader isr = new InputStreamReader(bais, decoder);
于 2011-02-03T13:08:37.287 に答える
3

これはコンストラクターの場合と同じです String(byte bytes[], int offset, int length, Charset charset)

このメソッドは、常に不正な形式の入力およびマップ不可能な文字シーケンスをこの文字セットのデフォルトの置換文字列に置き換えます。デコードプロセスをさらに制御する必要がある場合は、java.nio.charset.CharsetDecoderクラスを使用する必要があります。

を使用しCharsetDecoderて、別のを指定できますCodingErrorAction

于 2011-02-03T13:09:31.633 に答える