java按字节截取字符串

本文探讨了如何确定Oracle数据库中汉字占用的字节数,包括查询数据库字符集、检查服务器端字符集以及通过SQL查询字节长度的方法。此外,还提供了Java实现字符串截取的代码示例,以应对Oracle备注字段长度限制问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求:oracle有个备注长度只有100,但是不能扩大,只能截取java传输过程中的字符长度

如何知道一个汉字在Oracle数据库中具体占用几个字节?

方式一:这个其实和Oracle的配置是相关的,用以下语句查询当前数据库的字符集:

理论
	select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET';

可以得到如下结果:
如果value=ZHS16GBK,那么一个汉字占用2个字节,
如果value=AL32UTF8,那么一个汉字占用3个字节(这是Oracle数据库默认的)。

实际

所以可以看出我的数据库是占用2个字节
在这里插入图片描述

方式二:查看oracle server端字符集

理论
select userenv('language') from dual;

如果结果是下面这样的,一个汉字就占用两个字节
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
如果结果是下面这样的,那么一个汉字就占用三个字节
SIMPLIFIED CHINESE_CHINA.AL32UTF8

实际

在这里插入图片描述

方式三:也可以尝试用以下语句查询一个汉字占用的字节长度

理论

直接可以查看对应字符的长度(空格是1个长度)

select lengthb('你') from dual;
实际

在这里插入图片描述

java

实现代码

package com.zjnac.restfulapi.util;

import java.io.IOException;

/**
 * @ClassName CutStringUtil
 * @Description 按字节截取字符串
 * @Author Duplicator
 * @Date 2019/8/21 14:38
 * @Version 1.0
 **/
public class CutStringUtil {

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

        String str = "ab你好cd谢谢";
        int len = str.getBytes("gbk").length;
        for (int x = 0; x < len; x++) {
            System.out.println("截取" + (x + 1) + "字节结果时:"
                    + cutStringByGBK(str, x + 1));
        }
        String str1 = "ab你好cd杮";
        int len1 = str.getBytes("gbk").length;
        for (int x = 0; x < len1; x++) {
            System.out.println("截取" + (x + 1) + "字节结果时:"
                    + cutStringByUTF8(str1, x + 1));
        }
    }

    // 使用UTF-8编码表进行截取字符串,一个汉字对应三个负数,一个英文字符对应一个正数
    public static String cutStringByUTF8(String str, int len) throws IOException {
        if(str==null){
            return null;
        }
        //前提不知道str他的长度,而指定的len长于实际str长度数组下标超过异常
        int actualLen = str.getBytes("gbk").length;
        if(actualLen<len){
            len = actualLen;
        }
        byte[] buf = str.getBytes("utf-8");
        int count = 0;
        for (int x = len - 1; x >= 0; x--) {
            if (buf[x] < 0) {
                count++;
            } else {
                break;
            }
        }
        if (count % 3 == 0) {
            return new String(buf, 0, len, "utf-8");
        } else if (count % 3 == 1) {
            return new String(buf, 0, len - 1, "utf-8");
        } else {
            return new String(buf, 0, len - 2, "utf-8");
        }
    }

    // 使用GBK编码表进行字符串的截取,一个英文字符对应码表一个正数,一个汉字对应两个负数
    public static String cutStringByGBK(String str, int len)
            throws IOException {
        if(str==null){
            return null;
        }
        int actualLen = str.getBytes("gbk").length;
        if(actualLen<len){
            len = actualLen;
        }
        byte[] buf = str.getBytes("gbk");
        int count = 0;
        for (int x = len - 1; x >= 0; x--) {
            //统计按字节截取的字符串中,中文字符串有几个字节
            //小于0的是中文的部分
            if (buf[x] < 0) {
                count++;
            } else {
                break;
            }
        }
        if (count % 2 == 0) {
            return new String(buf, 0, len, "gbk");
        } else {
            return new String(buf, 0, len - 1, "gbk");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值