java多字节字符串截取,如果按照通常的按字节长度截取,有可能从字符内部截断,导致结果字符串最后出现乱码,因此需要做一下特别处理。

算法思路

1.先按照实际要截取的字节长度,复制一份字节数组

2.转换回字符串,计算字符长度resLen,并按这个长度截取原字符串

3.计算截取的字符串的字节数是否等于需求长度len,相等则直接返回,不相等,则在resLen的基础上减1再截取,则为需要的结果

此算法截取的结果为向前截取,即保证最终截取的字节长度不能超过需求长度len,比如gbk字符集,“一二三四五”,截取3字节,结果应为"一",实际长度为2字节,第3个字节为半个中文,属于无效字符,需要去掉。

在转换字节数组时,需要指定字符集,在不同的字符集下,转换出来的字节数组长度是不一样的。

经测试,效率要高于按循环的算法,尤其在截取长度较大时,性能较优

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static String substr(String str, int len, 

                                String cs) throws UnsupportedEncodingException {

        byte[] br = new byte[len];

        byte[] bt = str.getBytes(cs);

        System.arraycopy(bt, 0, br, 0, len);

        String res = new String(br, cs);

        int resLen = res.length();

        if (str.substring(0, resLen).getBytes(cs).length > len) {

            res = str.substring(0, resLen - 1);

        }

        return res;

    }