【问题标题】:Checking if a string is UTF-8 compatible for mySQL检查字符串是否与 mySQL 兼容 UTF-8
【发布时间】:2014-03-18 22:36:26
【问题描述】:

我们有只支持 UTF-8 字符集的旧版 mySQL 数据库。 Java 中有没有办法检测给定的字符串是否与 UTF-8 兼容?

【问题讨论】:

  • 没有“Mysql utf-8”这样的东西。 UTF-8 本身就是一个标准。要么是 UTF-8/unicode 感知的,要么不是。
  • @MarcB。谢谢。我更新了问题。
  • 不仅数据库端和java端应该支持UTF-8(两者都支持),而且如果是MySQL,还必须设置通过JDBC驱动的通信,见here跨度>
  • @JoopEggen。谢谢。我们检查了 JDBC 驱动程序,它设置正确。当我们遇到旧版本的 mySQL 无法处理的 UTF8MB4 字符串时的问题。

标签: java mysql string utf-8 character-encoding


【解决方案1】:
public static boolean isUTF8MB4(String s) {
    for (int i = 0; i < s.length(); ++i) {
        int bytes = s.substring(i, i + 1).getBytes(StandardCharsets.UTF_8);
        if (bytes > 3) {
            return true;
        }
    }
    return false;
}

上面的实现似乎最好,但除此之外:

public static boolean isUTF8MB4(String s) {
    for (int i = 0; i < s.length(); ) {
        int codePoint = s.codePointAt(i);
        int bytes = Character.charCount(codePoint);
        if (bytes > 3) {
            return true;
        }
        i += bytes;
    }
    return false;
}

这可能会更频繁地失败。

【讨论】:

  • 谢谢乔普。但是我们已经有了检测 UTF8MB4 的代码:stackoverflow.com/a/21478020/420558。我们正在寻找的是判断一个字符串是否兼容 UTF8。
  • Java String 是 Unicode,没有 UTF-8 问题。我的印象是,只要旧 MySQL 将 Unicode 代码点(字符)编码为不超过 3 个字节,它就可以处理 UTF-8。 wikipedia 表示以 U+10000 (java 0x10000) 开头的代码点有问题。
  • 你好乔普。听起来我们需要重新表述这个问题……我们想说的是,我们的旧 mySQL 数据库不支持所有字符集(例如:UTF8MB4,但也支持其他字符集)。因此,在 java 中——在我们尝试插入将导致 mySQL 抛出异常的字符串之前——我们想要确定该字符串是否与 UTF8 兼容。如果不是,那么我们在进行插入之前处理这种情况。那么,我们如何判断字符串是否兼容 UTF8?
  • 所以“UTF8”在此上下文中是旧 MySQL UTF-8 实现的名称。这是最新的标准 UTF-8 减去 UTF8MB4 特定部分(每个 Unicode 字符超过 3 个字节的多字节序列)。
【解决方案2】:

每个字符串都兼容 UTF-8。只需在数据库和 MySQL 驱动程序中正确设置编码即可。

唯一的问题是 UTF-8 编码字符串的字节长度可能比.length() 所说的要大。 Here's a Java implementation of a function to measure how many bytes a string will take after encoding to UTF-8.

编辑:由于 Saqib 指出旧的 MySQL 实际上并不支持 UTF-8,而仅支持其 BMP 子集,因此您可以使用 string.length()==string.codePointCount(0,string.length()) 检查字符串是否包含 BMP 之外的代码点(“true”表示“所有代码点都是在 BMP") 并使用 string.replaceAll("[^\u0000-\uffff]", "") 删除它们

【讨论】:

  • 我不认为这是正确的。您不能将 UTF8MB4 字符串存储在仅支持 UTF8 的旧 mySQL 数据库中。
  • Every String is UTF-8 compatible libidn2 有函数u8_check 来检查二进制字符串是否是有效的UTF-8
【解决方案3】:

MySQLdefines

名为 utf8 的字符集每个字符最多使用三个字节,并且仅包含 BMP 字符。

因此这个功能应该可以工作:

private boolean isValidUTF8(final String string) {
    for (int i = 0; i < string.length(); i++) {
        final char c = string.charAt(i);
        if (!Character.isBmpCodePoint(c)) {
            return false;
        }
    }
    return true;
 }

【讨论】:

    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    • 2016-07-18
    • 2018-09-07
    • 2018-09-03
    • 2011-01-13
    • 2013-08-16
    相关资源
    最近更新 更多