【问题标题】:How can I check if a String is encodable in some encoding?如何检查字符串是否可在某些编码中编码?
【发布时间】:2013-06-03 17:03:01
【问题描述】:

以下测试在转换后的 Latin1 上失败,因为非法字符被替换为值为 63(问号)的字节。问题是这些字符应该更好地引起一些异常......

  @Test
  public void testEncoding() throws UnsupportedEncodingException {
    final String czech = "Řízeček a šampáňo a žízeň";
    // okay
    final byte[] bytesInLatin2 = czech.getBytes("ISO8859-2");
    // different bytes, but okay
    final byte[] bytesInWin1250 = czech.getBytes("Windows-1250");
    // different bytes, but okay
    final byte[] bytesInUtf8 = czech.getBytes("UTF-8");
    // nonsense; Ř,č,... are not in Latin1 code set!!!
    final byte[] bytesInLatin1 = czech.getBytes("ISO8859-1");

    System.out.println(Arrays.toString(bytesInLatin2));
    System.out.println(Arrays.toString(bytesInWin1250));
    System.out.println(Arrays.toString(bytesInUtf8));
    System.out.println(Arrays.toString(bytesInLatin1));
    System.out.flush();

    final String latin2 = new String(bytesInLatin2, "ISO8859-2");
    final String win1250 = new String(bytesInWin1250, "Windows-1250");
    final String utf8 = new String(bytesInUtf8, "UTF-8");
    final String latin1 = new String(bytesInLatin1, "ISO8859-1");

    Assert.assertEquals("latin2", czech, latin2);
    Assert.assertEquals("win1250", czech, win1250);
    Assert.assertEquals("utf8", czech, utf8);
    Assert.assertEquals("latin1", czech, latin1); // this test will fail!
  }

由于 Java 的这种行为,数据最终损坏的情况有很多。如果字符串可以通过某种编码进行编码,是否有任何库可用于验证字符串?

【问题讨论】:

    标签: java string encoding character-encoding


    【解决方案1】:

    我怀疑你正在寻找CharsetEncoder.canEncode(CharSequence)

    Charset latin2 = Charset.forName("ISO8859-2");
    boolean validInLatin2 = latin2.newEncoder().canEncode(czech);
    ...
    

    【讨论】:

    • +1,不错!我什至不知道这存在... 附带问题:这些CharSequences 是否不能使用 UTF-8 编码?
    • @fge:只有无效的(例如有一半代理对的)。
    【解决方案2】:

    作为 Jon Skeet 建议的替代方案,您也可以使用CharsetEncoder 类直接进行编码(使用encode 方法),但首先调用onMalformedInputonUnmappableCharacter 方法来指定编码器遇到错误输入时应该这样做。

    这样大部分时间你只是在做一个简单的编码调用,但如果出现任何问题你会得到一个异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-17
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多