背景:公司生产线上出现异常,报的错是记录日志时数据库长度超出,导致异常,经查询发现是由于在计算byte长度时出了问题。

问题代码:

                    operatorLog.setOperAfterData(updateString.substring(0,updateString.getBytes("gbk").length > 1024?1024-(updateString.getBytes("gbk").length - updateString.length()):updateString.length()));

只有一行,这么长一行代码,压根没法看,分解成如下代码:

                    int defaultLen = updateString.length();
int gbkLen = updateString.getBytes("gbk").length;
operatorLog.setOperAfterData(updateString.substring(0,
defaultLen > 1024 ? 1024 - (gbkLen - defaultLen) : defaultLen));

笔者目地是想让保存的日志长度限制为1024个字节-byte(不管中文还是英文);当文本中出现中文,一个字符占用两个bytes,但是英文只占用一个byte,首先得计算出文字中包含的中文字符个数,知道差别后不难得出中文长度为:gbkLen - defaultLen,假设字符长度为1025,里面中文有5个,此时gbkLength = 1030, defaultLen = 1025,此时得出的子字符串为1024 - 5 = 1019个字符,其实此时能保证这1019能够存储在1024字节的数据库字段中,因为这1019字符长度肯定不会超过1024;这是作者想要的目地

发生问题场景:

当字符里全是中文的时候会出现什么问题,比如1025个汉字,那得到的字符将是1024 - 1025 = -1,那在取子串的时候updateString.substring(0, -1);,这个时候就发生了我们在生产上跑的异常,数组越界,不可能取索引为-1的元素的值

当时想的解决办法:

当时就有点被绕进去了,最后写出来的代码竟然和原作者差不多一样,只是在最前面加了先取原串的1024个字符,这样确实是当汉字长度小于1024时,问题都好解决,但是实际情况往往不是这样的

问题依然出现:

目标是为了取得1024个字节,但是取得的值完全不对,此时假设字符串长度为513,全为汉字,做为字符串存至数据库时会超出长度1024,此时字节长度为1026

简单解决:

最后由于我们只是简单的记录日志,不做过多处理,决定只取512长度,超过512就不取了

真正解决:

在网上搜索后找到真正的解决办法:

使用循环对字条串的每个字符进行是否为中文判断或都判断将字符一个个读出来,取到规定长度:

String.valueOf(c).getBytes("GBK").length > 1

参考:

http://jingyan.baidu.com/article/1709ad80d383d44634c4f0dc.html

http://www.cnblogs.com/myphoebe/archive/2011/12/20/2294171.html

引伸:

Q: oracle在对字符进行存储时到底使用的是哪种方式,bytes?char?

A: 在定义时,oracle默认是以byte定义的,就是说如果定义成varchar(20), 理论上来说只能存储10个汉字,但对不同编码方式来说,又不一样,一个汉字在oracle中可能会占3个byte,这个是由oracle本身决定,有方法可以解决此问题,在定义表格时这样字义

create table ABC_TABLE (A_FIELD varchar2(20 char)) 

就表示字段A_FIELD会以字符存储,而不是以字节,当然对数据库也可以进行配置,参考以下:

http://doingwell.iteye.com/blog/972938

http://blog.csdn.net/yh555/article/details/6890000

String之-如何取得精确byte长度字符串的更多相关文章

  1. C#中字节数组byte[]和字符串string类型的相互转换

    C#中字节数组byte[]和字符串string类型的相互转换: string转byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBy ...

  2. leetCode题解之寻找string中最后一个word的长度

    1.题目描述 返回一个 string中最后一个单词的长度.单词定义为没有空格的连续的字符,比如 ‘a’,'akkk'. 2.问题分析 从后向前扫描,如果string是以空格‘  ’结尾的,就不用计数, ...

  3. asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得

    <?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...

  4. Application.StartupPath获取执行文件路径substring()取特定长度字符串取得根目录

    Application.StartupPath获取执行文件路径substring()取特定长度字符串取得根目录 2012-07-20 10:48 257人阅读 评论(0) 收藏 举报 path usi ...

  5. Java String类相关知识梳理(含字符串常量池(String Pool)知识)

    目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(S ...

  6. String 对象是不动态改变长度的

    在java里 String 对象是不动态改变长度的,只有先转化成StringBuffer,插入处理后在转回. 如 StringBuffer str = new StringBuffer("T ...

  7. byte[] 与字符串转换

    //取值之后进行 StringBuffer buffer=new StringBuffer(); for (int i = 0; i < enBytes.length; i++) { if(i! ...

  8. C语言 realloc为什么要有返回值,realloc返回值具体解释/(解决随意长度字符串输入问题)。

    在C语言操作中会用到大量的内存操作,当中非经常常使用的一个是realloc(). 由字面意思能够知道,该函数的作用是用于又一次分配内存. 使用方式例如以下: NewPtr=(数据类型*)realloc ...

  9. C#利用 string.Join 泛型集合快速转换拼接字符串

    C#利用 string.Join 泛型集合快速转换拼接字符串 List<int> superior_list = new List<int>(); superior_list. ...

随机推荐

  1. Apache和PHP的安装

    最近看了一些教科书,可能是印刷的缘故,只是一个空格没有打印,再加上网上的很多博客文章只是顺手转载,并没有仔细的检查,还有php和apache之间的版本问题,害得我花了4,5小时的时间才搞定环境的搭配. ...

  2. 自动化监控利器-Zabbix

    转自: http://www.xuliangwei.com/xubusi/117.html   1.1为何需要监控系统 在一个IT环境中会存在各种各样的设备,例如:硬件设备.软件设备.其系统的构成也是 ...

  3. Max Subsequence

    一个sequence,里面都是整数,求最长的subsequence的长度,使得这个subsquence的最大值和最小值相差不超过1. 比如[1,3,2,2,5,2,3,7]最长的subsequence ...

  4. Binary Tree Upside Down

    Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that ...

  5. emmet 太 hackble 了 。。。

    http://www.open-open.com/lib/view/open1451954899292.html

  6. POJ 3414

    http://poj.org/problem?id=3414 这是一个广搜的题目,不难,就是有些许麻烦.对于练习还是个不错的题目. 题意就是给你两个杯子,这两个杯子的容量分别为a和b,要你通过一些操作 ...

  7. svn上传报Authorization failed错误解决办法

    svn上传文件时没有弹出用户登录界面,而是直接报Authorization failed错误.出现该问题基本都是三个配置文件的问题,下面把这个文件列出来 svnserve.conf配置文件中的 [ge ...

  8. 推荐一篇 OAuth 2.0 必读文章

    http://www.cnblogs.com/artech/p/oauth-03.html 共计有3篇相关内容,请仔细阅读! 再说一下我用box api 开发时的问题,在 box 程序登记页面: 对于 ...

  9. android上的图片占用内存问题

    近日正在把ios程序移植到android上,以前没做过android的程序,于是,想当然地把ios的图片资源放到了android工程的drawable文件夹下,这些图片都是png. 程序界面也很正常. ...

  10. java压缩

    /* @description:压缩文件操作 * @param filePath 要压缩的文件路径 * @param descDir 压缩文件保存的路径 d:\\aaa.zip */ public s ...