在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符。
但对应的字节数不同,一个汉字占两个字节。
定义一个方法,按照指定的字节数来取子串。
如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,那么半个就要舍弃。如果取四个字节就是“ab你”,取五个字节还是“ab你”。
@Test
// 观察一下字符的编码规律
public void observe() {
String str = "ab你好123好琲琲2332ss"; //"UTF-8"里汉字一般占三个字节,"GBK"里汉字是两个字节
byte bs[] = str.getBytes();
for (byte b : bs) {
System.out.print(b + " ");
}
System.out.println();
}
private String cutStringByByte(String str, int len) throws IOException {
if(System.getProperty("file.enconding").equalsIgnoreCase("GBK")){
return cutStringByByteGBK(str, len);
}else if(System.getProperty("file.encoding").equalsIgnoreCase("UTF-8")){ //避免"UTF-8"大小写
return cutStringByByteUTF8(str, len);
}else{
throw new RuntimeException("不支持该系统编码!");
}
}
private String cutStringByByteGBK(String str, int len) throws IOException {
try {
byte bs[] = str.getBytes("GBK");
// 从len位置开始往前,统计值为负的连续字节个数
int count = 0;
for (int i = len - 1; i >= 0; i++) { //从后往前遍历字节数的数值
if (bs[i] < 0) {
count++;
} else {
break;
}
}
// 如果字节数为偶数,则刚好汉字完整
if (count % 2 == 0) {
return new String(bs, 0, len, "GBK");
} else { // 否则要丢弃最后一个字节
return new String(bs, 0, len - 1, "GBK");
}
} catch (Exception e) {
throw new RuntimeException("不支持GBK编码!"); //穿透后台抛异常
}
}
private String cutStringByByteUTF8(String str, int len) {
try {
byte bs[] = str.getBytes("UTF-8");
// 从len位置开始往前,统计值为负的连续字节个数
int count = 0;
for (int i = len - 1; i >= 0; i--) { //从后往前遍历
if (bs[i] < 0) {
count++;
} else {
break;
}
}
// 如果字节数为3的倍,则刚好汉字完整,否则要丢弃最后一个或二个字节
return new String(bs, 0, len - count % 3, "utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("不支持UTF-8编码");
}
}
这里可以先测试系统编码类型,之后再进行解题!