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

/*
 * 【练习】
 * 在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你
 */


















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值