亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Java 中查找不能存儲在 MySQL“utf8”列中的字符

如何在 Java 中查找不能存儲在 MySQL“utf8”列中的字符

一只甜甜圈 2023-02-23 09:58:57
我使用 MySQL 5.7,我有一個表,其中有一列使用“utf8”字符集。不幸的是,它不是 utf8mb4,因此當我的應用程序嘗試插入超出“utf8”(例如表情符號)范圍的字符時,我總是會收到錯誤消息。不幸的是,我不能很快將字符集更改為“utf8mb4”,所以我想知道是否有可能在將錯誤插入到表中之前檢測到那些導致錯誤發生的字符,并讓我們的客戶知道他們不能使用它們。我在某處讀到 U+0000 到 U+FFFF 范圍之外的任何內容都會導致錯誤發生。我的應用程序是在 Java 8 中實現的。因此,我的問題是:如何編寫代碼來從 String 實例中找到此類有問題的字符?下面的代碼做我想做的事嗎?import java.util.Set;import java.util.stream.Collectors;class Utf8Mb3Validator {    /**     * finds characters which can’t be stored in a MySQL “utf8” column out of a given String.     *     * @param input a String which you want to check     * @return a Set which contains strings that can't be inserted into MySQL "utf8" columns     */    Set<String> findProblematicStrings(String input) {        // References:        // https://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb3.html        // https://www.oracle.com/technetwork/java/javase/downloads/supplementary-142654.html?printOnly=1        // https://stackoverflow.com/q/56800767/3591946        return input                .codePoints() // get Unicode code points                .filter(codePoint -> Character.charCount(codePoint) > 1) // search for non-BMP characters                .mapToObj(codePoint -> new String(Character.toChars(codePoint))) // convert code points into Strings                .collect(Collectors.toSet());    }}我還將這個問題發布到 MySQL 論壇:https://forums.mysql.com/read.php ?39,675862,675862#msg-675862
查看完整描述

2 回答

?
米琪卡哇伊

TA貢獻1998條經驗 獲得超6個贊

事實上,MySQLutf8在當時是正確的,因為 UTF-8 多字節序列最多只有 3 個字節。但是 Unicode 有更多的符號,UTF-8 也增長了。并且只能 utf8mb4做到。


但是最多 3 個字節都可以:


return input

      .codePoints()

      .filter(codePoint -> codePoint >= 256) // Optional heuristic optimisation

      .mapToObj(codePoint -> new String(Character.toChars(codePoint)))

      .filter(cpString -> cpString.getBytes(StandardCharsets.UTF_8).length > 3)

      .collect(Collectors.toSet())

或者只是U+FFFF 以上的所有代碼點:


return input

      .codePoints()

      .filter(codePoint -> codePoint >= 0x1_0000)

      .mapToObj(codePoint -> new String(Character.toChars(codePoint)))

      .collect(Collectors.toSet());

老實說,我需要研究是否Character.charCount(codePoint)也可以使用,因為它檢查 UTF-16 中的代理項對,而不是 UTF-8 中的字節數。


有用的可能是Character.getName(codePoint)將代碼點替換為(如果字段有足夠長的大小)。


查看完整回答
反對 回復 2023-02-23
?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

如果 Java 中有一種方法可以生成 -encoded 字符串的十六進制表示,則在字符串中UTF-8搜索一個字節。F0

如果 Java 中有一種方法可以生成編碼字符串的 16 位表示UTF-16,則搜索包含D8xx-DFFF值的任何 16 位。

(指出一些這樣的方法,也許我可以詳細說明。)


查看完整回答
反對 回復 2023-02-23
  • 2 回答
  • 0 關注
  • 123 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號