首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 按位元組截取含中文字串完整解法

     編輯:Java 相關知識

問題背景

資料庫欄位多為定長位元組(如 Oracle VARCHAR2(100 BYTE)),若直接用 substring(int begin, int end) 截取字元數,遇到中英文混排會導致實際位元組長度超限,寫入失敗。核心難點:中文字元在 UTF-8 佔 3 位元組,GBK 佔 2 位元組,英文僅 1 位元組,截取時不能將雙位元組字元「切半」。

核心思路

  1. 指定編碼(通常 UTF-8 或 GBK),將字串轉為 byte[]
  2. 若總位元組數 ≤ 限制,直接返回
  3. 否則從末尾向前逐字元檢查:累加各字元位元組長度,超限則捨棄該字元
  4. 最終組合合法字元返回

關鍵代碼實現(UTF-8 版)

public static String substringByByte(String str, int maxBytes, String charset) throws UnsupportedEncodingException {
    if (str == null || str.isEmpty() || maxBytes <= 0) return str;
    byte[] bytes = str.getBytes(charset);
    if (bytes.length <= maxBytes) return str;

    StringBuilder sb = new StringBuilder();
    int count = 0;
    for (char c : str.toCharArray()) {
        int charBytes = String.valueOf(c).getBytes(charset).length;
        if (count + charBytes > maxBytes) break;
        sb.append(c);
        count += charBytes;
    }
    return sb.toString();
}

遞歸版(原文思路)

public static String truncateRecursive(String s, int maxBytes, String charset) throws UnsupportedEncodingException {
    if (s.getBytes(charset).length <= maxBytes) return s;
    return truncateRecursive(s.substring(0, s.length() - 1), maxBytes, charset);
}

注意:遞歸版效能較差(重複編碼),生產環境建議用迭代版。

編碼對照表(關鍵知識點)

編碼英文中文
GB2312 / GBK / GB180301 位元組2 位元組
UTF-81 位元組3 位元組
UTF-16BE / LE2 位元組2 位元組
ISO-8859-11 位元組1 位元組(不可用於中文)

進階:判斷是否為漢字

public static boolean isChineseChar(char c) {
    // UTF-8 下中文≥3 bytes,英文=1 byte
    return String.valueOf(c).getBytes(StandardCharsets.UTF_8).length > 1;
}

總結

按位元組截取的本質是在指定編碼下逐字元累加位元組長度。生產代碼務必:

  • 明確指定 Charset,避免平台預設編碼差異
  • 優先用 StringBuilder 迭代構建,避免遞歸/重複編碼
  • 單元測試覆蓋:純英文、純中文、中英混雜、邊界值(剛好等於/超 1 位元組)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved