【问题标题】:Why does US-ASCII encoding accept non US-ASCII characters?为什么 US-ASCII 编码接受非 US-ASCII 字符?
【发布时间】:2011-06-20 15:55:54
【问题描述】:

考虑以下代码:

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 中的什么地方要求这种行为?

【问题讨论】:

    标签: java encoding utf-8 ascii non-ascii-characters


    【解决方案1】:

    我会说,这与构造函数相同 String(byte bytes[], int offset, int length, Charset charset):

    此方法总是用此字符集的默认替换字符串替换格式错误的输入和不可映射的字符序列。当需要对解码过程进行更多控制时,应使用 java.nio.charset.CharsetDecoder 类。

    使用CharsetDecoder,您可以指定不同的CodingErrorAction

    【讨论】:

      【解决方案2】:

      在输入流中查找不可解码字节时的默认操作是将它们替换为 Unicode 字符 U+FFFD REPLACEMENT CHARACTER

      如果你想改变它,你可以传递一个CharacterDecoder to the InputStreamReader,它配置了一个不同的CodingErrorAction

      CharsetDecoder decoder = Charset.forName(usingEncoding).newDecoder();
      decoder.onMalformedInput(CodingErrorAction.REPORT);
      InputStreamReader isr = new InputStreamReader(bais, decoder);
      

      【讨论】:

      • 感谢您的回答。问题是我不能轻易更改创建InputStreamReader 的代码,因为它不是我的 - org.apache.tools.ant.taskdefs.SQLExec.Transaction.runTransaction(PrintStream)。得知 Ant 的 <sql> 任务的 encoding 属性并不能防止格式错误的输入,我感到很惊讶。
      • @Grzegorz:我认为这是一个错误。至少在指定encoding 时,任务应该强制执行编码,包括报告错误。如果未指定,那么容错可能会更好。也许添加一个strictEncoding 属性或类似的东西是合适的。
      • 我在 Ant 的错误数据库中提交了一个问题:issues.apache.org/bugzilla/show_bug.cgi?id=50715,但我不希望问题很快得到解决。
      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      相关资源
      最近更新 更多