日期:2014-05-20  浏览次数:20823 次

java按字节拆分字符串 后在拼成字符串
是这样的一个方法
public static void main(String[] args) throws UnsupportedEncodingException {
    String arr[] = splitByByteSize("abc刘defghijklmnopqrstuvwxyz",4);
    int byteLen = 0;
    for(int i=0;i<arr.length;i++){
        byteLen+=arr[i].getBytes().length;
    }
    byte[] bytes = new byte[byteLen];
    int offset = 0;
    for(int i=0;i<arr.length;i++){
        System.arraycopy(arr[i].getBytes("utf-8"), 0, bytes, offset, arr[i].getBytes("utf-8").length);
        offset += arr[i].getBytes("utf-8").length;
    }

    System.out.println(">>"+new String(bytes));
}

public static String[] splitByByteSize(String content, int size) throws UnsupportedEncodingException{
    byte[] bytes = content.getBytes("utf-8");
    int totalSize = bytes.length;
    int partNum = 0;
    if(totalSize == 0){
        return new String[0];
    }
    if(totalSize % size == 0){
        partNum = totalSize / size;
    }else{
        partNum = totalSize / size + 1;
    }
    String[] arr = new String[partNum];
    int offset = 0;
    byte newBytes[] = new byte[size];
    for(int i=0;i<partNum-1;i++){
        System.arraycopy(bytes, offset, newBytes, 0, size);
        arr[i] = new String(newBytes,"utf-8");
        offset += size;
    }
    System.arraycopy(bytes, offset, newBytes, 0, totalSize-offset);
    arr[partNum-1] = new String(newBytes,"utf-8");
    return arr;

}


按字节拆分后等字节的放到String数组中。另外有个方法接收String数组后在拼成content原来的值。现在是如果有中文,按字节拆分会有乱码。但是感觉后面按照String数组拼成字符串应该不会乱码。但是还是乱码。请问怎么做才能在用返回的String数组拼成字符串不乱码。
------解决方案--------------------
无法保证按照4分割byte数组,不会将中文的byte给分割开。


------解决方案--------------------
utf-8是变长编码,理论上是满足iscii的字符占2个字节,中文等占3个字节, 你没4个字节拆分会把中文拆开掉
------解决方案--------------------
拆分字符的时候,不能将字符的数据截断。
截断后的数据,再用指定编码方式进行编码时,由于不是一个完整的字符数据,会产生乱码现象;
显示的时候成为乱码还不太重要,重要的是,这个碎片数据无法被编码规则正确解释,
随之而来的,将碎片数据解码成的字符数据中,乱码字符由于不被正确识别,在向二进制数据编码时,是无法被正确还原成原有的碎片数据的。
所以,楼主想要还原成完整的字符数据,
那么,唯一可靠的办法就是,在拆分字符的时候,不能截断字符的数据
------解决方案--------------------
或者考虑在拼接的过程中,除了最后一个子字符串以外,其他字符串的解码数据,都用定长数据进行拼接。
不明白?
就是说,你指定了拆分字符串时,二进制数据的长度(那个size参数),那么,你在还原字符串的时候,
每个分组(除最后一个分组外)都要按照指定的二进制长度(那个size值)来进行拼接。
如果楼主采用的编码解码方式中,对于未包含字符数据不做替换处理的话,原有数据还是有很大的可能性被还原的。
------解决方案--------------------
我在做注册码时也遇到过类似的问题。
原因就出在你把拆分完的byte[]直接转换为String。也就是line 34
new String()如果遇到不完整的片段,会根据编码自动补位,补出来的内容当然就是乱码了。

比较一下前后的十六进制编码就知道了,比如String[] arr = splitByByteSize("abc刘de",4)
"abc刘de"的十六进制码:(红的是“刘”)
97 98 99 -27 -120 -104 100 101 
arr[0]:
97 98 99 -17 -65 -67
arr[1]:
-17 -65 -67 -17 -65 -67 100 101 
很明显line34 前,两个部分是
97 98 99 -27 和 -120 -104 100 101
new String()后就变成
97 98 99 -17 -65 -67 和 -17 -65 -67 -17 -65 -67 100 101 了

所以你想要还原数据,就不要在编码转换过程中new String(),都用byte数组操作就没事了
个人浅见。。。希望对你有帮助