您的位置:首页 > 其它

24-IO流-70-IO流(练习-按字节截取字符串)

2015-08-11 16:41 253 查看
/*
* 【练习】
* 在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是4个字符,但对应的字节数不同,一个汉字=2字节,一个字母=
* 1字节。
*
* 定义一个方法,按照最大的字节数来取字符串。
*
* 如:对于“ab你好”,如果取3个字节,那么子串就是ab与“你”字的半个,那么这半个“你”字就要舍弃(因为如果显示是有问题的
* )。如果取4个字节就是“ab你”,取5个字节还是“ab你”(5个字节=ab你+“好”字半边,为了显示正常,舍弃“好”字半边)。
*/

/**
* 【思路】
* “ab你好”对应的GBK编码是:97 98 -60 -29 -70 -61,
* 设取x字节,那么直接取出从0到x字节的子串,获取最后一个编码(对应编号是x-1,设取5个字节,直接拿最后一个字节-70,对应
* 编号为4),之后判断最后一个编码是否为负数,是负数说明当前编码是汉字的编码,不是说明是字母的编码,若不是负数,直接将
* 0到x的子串打印输出即可;若是负数,从该编码位置从后往前依次判断每一个编码是否为负数,最终看负数编码的个数,若为奇数,
* 则舍弃最后一个编码(因为1汉字=2字节,奇数说明最后一个编码对应某一汉字的一半),若为偶数,直接打印输出。
*/

package test;

import java.io.UnsupportedEncodingException;

public class IOTest {

public static void main(String[] args) throws UnsupportedEncodingException {

String str = "ab你好";

int len = str.getBytes("GBK").length;//获取str用GBK编码的长度

for(int x = 1; x<len;x++){
System.out.println("截取"+x+"个字节结果是:"+cutStringByByte(str, x));
}

}

public static String cutStringByByte(String str, int len) throws UnsupportedEncodingException{
//参数str是原字符串,参数len是从原字符串中所要截取的字节数

//将字符串str变成字节数组
byte[] buf = str.getBytes("GBK");

int count = 0;//计数器,用于计算str内汉字的个数

for(int x = len-1; x>0 ; x--){

if(buf[x]<0)//如果当前位置编码为负数,说明是中文,计数器自增
count++;
else//否则是英文,直接跳出循环
break;
}
//如果有偶数个汉字,直接将buf全部解码,如果有奇数个汉字,舍弃最后一个编码,将剩余解码
if(count%2==0)
return new String(buf,0,len,"GBK");
else
return new String(buf,0,len-1,"GBK");
}

}

/*
* 【运行结果】
* 截取1个字节结果是:a
* 截取2个字节结果是:ab
* 截取3个字节结果是:ab
* 截取4个字节结果是:ab你
* 截取5个字节结果是:ab你
*/

=============================分割线=============================

//前面是用GBK验证的,这里用UTF-8验证

package test;

import java.io.UnsupportedEncodingException;

public class IOTest2 {

public static void main(String[] args) throws UnsupportedEncodingException {

String str = "ab你好";

int len = str.getBytes("UTF-8").length;

for(int x = 1;x<len;x++){

System.out.println("截取"+x+"个字节的结果是:"+cutStringByU8Byte(str,x));

}
}

public static String cutStringByU8Byte(String str, int len) throws UnsupportedEncodingException {

byte[] buf = str.getBytes("UTF-8");

int count=0;

for(int x=len-1;x<len;x--){

if(buf[x]<0)
count++;
else
break;
}

if(count%3==0)//UTF-8码表一个汉字占3个字节,所以这里count%3,其结果只有三种可能:0、1、2
return new String(buf,0,len,"UTF-8");//若count%3==0,说明所要截取的len个字节,最后正好是完整的汉字
else if(count%3==1)
return new String(buf,0,len-1,"UTF-8");//若count%3==1,说明最后是1/3个汉字,直接舍弃
else
return new String(buf,0,len-2,"UTF-8");//若count%3==2,说明最后是2/3个汉字,直接舍弃
}

}

/*
* 【运行结果】
* 截取1个字节的结果是:a
* 截取2个字节的结果是:ab
* 截取3个字节的结果是:ab
* 截取4个字节的结果是:ab
* 截取5个字节的结果是:ab你
* 截取6个字节的结果是:ab你
* 截取7个字节的结果是:ab你
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: