浅析Oracle varchar2类型及根据字符集获取在Java中的字符字节/截取工具类

   首先varchar2(byte)最大是4000字节。

   varchar2(50)  表示该字段类型为varchar2类型,长度为50,可以存单字节字符50个。

    长度跟你的字符集和其编码都有关系:

  如果字符集是16位编码的,ZHS16GBK(其实就是GBK,),那么每个字符16位、2字节,所以可以容纳2000字符。

  如果是32位编码的字符集,那么只能存储 1000个字符。

  如何查看自己数据库字符集和编码呢?

select userenv('language') from dual;

 分享一个获取Java中字符串类型字节长度和根据字节截取的工具类

 

/**
     * 按字节长度截取字符串
     *
     * @param orgin       需要截取的字符串
     * @param blength     需要保留的字节长度
     * @param charsetName 编码,对于字符集为UTF-8的数据库,请指定编码为UTF-8;字符集为GBK的数据库,请指定编码GBK
     * @return 截取后的字符串
     * @throws UnsupportedEncodingException 不支持的字符编码
     */
    public static String subString4Byte(String orgin, int blength, String charsetName) {
        return subStringb2(orgin, blength, charsetName).get(0);
    }

    /**
     * @Auther: liuzujie
     * @Date: 2020/1/16 18:19
     * @Desc: 获取字符串字节数
     * @param: orgin(字符串)charsetName(字符集)
     */
    public static final int getStringByteLength(String orgin, String charsetName) {
        byte[] bs = new byte[0];
        try {
            bs = orgin.getBytes(charsetName);
        } catch (UnsupportedEncodingException e) {
            log.error("获取字符串字节数异常,orgin:{},charsetName:{},info:", orgin, charsetName, e);
        }
        return bs.length;
    }
    
    private static List<String> subStringb2(String orgin, int blength, String charsetName) {
        List<String> result = new ArrayList<>();
        int length;
        byte[] bs = new byte[0];
        try {
            bs = orgin.getBytes(charsetName);
            while (bs.length > 0) {
                length = blength;
                if (length >= bs.length) {
                    result.add(new String(bs, 0, bs.length, charsetName));
                    break;
                }
                if ("UTF8".equals(charsetName.toUpperCase()) || "UTF-8".equals(charsetName.toUpperCase())) {
                    while (length > 0) {
                        if ((bs[length] | 0x7F) == 0x7F) {
                            break;
                        }
                        if ((bs[length] & 0xC0) == 0xC0) {
                            break;
                        }
                        length--;
                    }
                } else if ("GBK".equals(charsetName.toUpperCase())) {
                    boolean removLast = length % 2 == 1;
                    for (int i = 0; i < length; i++) {
                        if ((bs[i] | 0x7F) == 0x7F) {
                            removLast = !removLast;
                        }
                    }
                    if (removLast) {
                        length--;
                    }
                } else if ("UNICODE".equals(charsetName.toUpperCase())) {
                    if (length % 2 == 1) {
                        length--;
                    }
                } else if ("UTF-16".equals(charsetName.toUpperCase()) || "UTF16".equals(charsetName.toUpperCase())) {
                    if (length % 2 == 1) {
                        length--;
                    }
                } else if ("UTF-16BE".equals(charsetName.toUpperCase())) {
                    if (length % 2 == 1) {
                        length--;
                    }
                } else if ("UTF-16LE".equals(charsetName.toUpperCase())) {
                    if (length % 2 == 1) {
                        length--;
                    }
                }
                result.add(new String(bs, 0, length, charsetName));
                bs = Arrays.copyOfRange(bs, length, bs.length);
            }
            if (result.size() == 0) {
                result.add("");
            }
        } catch (UnsupportedEncodingException e) {
            log.error("按字节长度分割字符串异常,orgin:{},blength:{},charsetName:{},info:", orgin, blength, charsetName, e);
        }
        return result;
    }

    public static void main(String[] args){
        String str="你。.3,3 2好2你223bdewj。";
        System.out.println(subString4Byte(str,9,"GBK"));
        System.out.println(getStringByteLength(str,"GBK"));
    }

 

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章