字符串按照字节截取

如果遇到截取字符串进行存储数据库时,注意⚠️:数据库中是按照字节存储的。所以在截取时需要注意
一般substring()是按照字符串的长度来进行的截取,所以有时即使你截取完入库时依旧会报,字段超长问题。

首先附上的是中英文在不同的编码下的字节长度:

import java.io.UnsupportedEncodingException;   
  
public class EncodeTest {   
    /**  
     * 打印字符串在指定编码下的字节数和编码名称到控制台  
     *   
     * @param s  
     *            字符串  
     * @param encodingName  
     *            编码格式  
     */  
    public static void printByteLength(String s, String encodingName) {   
        System.out.print("字节数:");   
        try {   
            System.out.print(s.getBytes(encodingName).length);   
        } catch (UnsupportedEncodingException e) {   
            e.printStackTrace();   
        }   
        System.out.println(";编码:" + encodingName);   
    }   
  
    public static void main(String[] args) {   
        String en = "A";   
        String ch = "人";   
  
        // 计算一个英文字母在各种编码下的字节数   
        System.out.println("英文字母:" + en);   
        EncodeTest.printByteLength(en, "GB2312");   
        EncodeTest.printByteLength(en, "GBK");   
        EncodeTest.printByteLength(en, "GB18030");   
        EncodeTest.printByteLength(en, "ISO-8859-1");   
        EncodeTest.printByteLength(en, "UTF-8");   
        EncodeTest.printByteLength(en, "UTF-16");   
        EncodeTest.printByteLength(en, "UTF-16BE");   
        EncodeTest.printByteLength(en, "UTF-16LE");   
  
        System.out.println();   
  
        // 计算一个中文汉字在各种编码下的字节数   
        System.out.println("中文汉字:" + ch);   
        EncodeTest.printByteLength(ch, "GB2312");   
        EncodeTest.printByteLength(ch, "GBK");   
        EncodeTest.printByteLength(ch, "GB18030");   
        EncodeTest.printByteLength(ch, "ISO-8859-1");   
        EncodeTest.printByteLength(ch, "UTF-8");   
        EncodeTest.printByteLength(ch, "UTF-16");   
        EncodeTest.printByteLength(ch, "UTF-16BE");   
        EncodeTest.printByteLength(ch, "UTF-16LE");   
    }   
}  
//运行结果

英文字母:A
字节数:1;编码:GB2312
字节数:1;编码:GBK
字节数:1;编码:GB18030
字节数:1;编码:ISO-8859-1
字节数:1;编码:UTF-8
字节数:4;编码:UTF-16
字节数:2;编码:UTF-16BE
字节数:2;编码:UTF-16LE
中文汉字:人
字节数:2;编码:GB2312
字节数:2;编码:GBK
字节数:2;编码:GB18030
字节数:1;编码:ISO-8859-1
字节数:3;编码:UTF-8
字节数:4;编码:UTF-16
字节数:2;编码:UTF-16BE
字节数:2;编码:UTF-16LE

下面开始处理字符串,这里有两种方式:个人建议采用第一种,第二种比较鸡肋采用倒减方式(和同事一起扯皮来的(o^^o))

// 入参都是 str:要处理的字符串 count:截取的字节数量
//第一种方式
   public String test(String str, int count) {
        String result = null;
        if (StringUtils.isBlank(str) || count <= 0) {
            return null;
        }
        byte[] bytes = str.getBytes();
        int length = bytes.length;
        if (length <= count) {
            return str;
        } else {
            result = new String(bytes, 0, count);
            int len = result.length();
            if (str.charAt(len - 1) != result.charAt(len - 1)) { //最后一个字符对比 只有汉字会出现不相等的情况
                if (len < 2) { // 如果字符串开头是汉字 并且截取字节小于此汉子字节 那么返回null 2表示字节长度 汉字编码为GBK时字节为2, UTF-8为3 默认StandardCharsets.UTF_8
                    return null;
                } else {
                    result = result.substring(0, len - 1);
                }

            }
        }

        return result;
    }
    //第二种方式
        public  String spiltByByte(String str, int count) {
        StringBuilder buffer = new StringBuilder();
        char[] chars = str.toCharArray();
        char testChar;
        for (int i = 0; ; i++) {
            if (count <= 0) {
                break;
            }
            testChar = str.charAt(i);
            buffer.append(testChar);
            count -= String.valueOf(testChar).getBytes().length;//某个字符的长度

            if (i + 1 < chars.length) {
                if (String.valueOf(chars[i + 1]).getBytes().length > count) {// 当前截取的字符子节长度大于剩余的子节长度,表明需要舍弃该字符
                    break;
                }

            }
        }
        return buffer.toString();
    }
上一篇:Java-如何解决乱码问题


下一篇:解决response.setHeade()中文乱码