Fastdb 之中文字符截取错误的问题

Fastdb C#版本中,如果定义字段类型为  CLI.FieldType.cli_asciiz,使用的过程中插入中文字符集会出现乱码的情况,

追查code发现是在对字符串缓冲区CopyBufferData的过程中直接fastdb直接使用了s.length获取了字符个数,而不是获取字节数,由于中文占位两个字节,所以导致数据copy不全,从而出现乱码。

不多说,修正代码如下:

protected int bytelengh(string str)

{

//使用Unicode编码的方式将字符串转换为字节数组,它将所有字符串(包括英文中文)全部以2个字节存储

byte[] bytestr = System.Text.Encoding.Unicode.GetBytes(str);

int j = 0;

for (int i = 0; i < bytestr.GetLength(0); i++)

{

//取余2是因为字节数组中所有的双数下标的元素都是unicode字符的第一个字节

if (i % 2 == 0)

{

j++;

}

else

{

//单数下标都是字符的第2个字节,如果一个字符第2个字节为0,则代表该Unicode字符是英文字符,否则为中文字符

if (bytestr[i] > 0)

{

j++;

}

}

}

return j;

}

protected unsafe void setValue(Object Value) {

switch((CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type) {

case CLI.FieldType.cli_oid:

*(uint*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToUInt32(Value);

break;

case CLI.FieldType.cli_int4:

*(int*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToInt32(Value);

break;

case CLI.FieldType.cli_bool:

case CLI.FieldType.cli_int1:

*(sbyte*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToSByte(Value);

break;

case CLI.FieldType.cli_int2:

*(Int16*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToInt16(Value);

break;

case CLI.FieldType.cli_int8:

*(Int64*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToInt64(Value);

break;

case CLI.FieldType.cli_real4:

*(Single*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToSingle(Value);

break;

case CLI.FieldType.cli_datetime:

case CLI.FieldType.cli_real8:

*(double*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer() = Convert.ToDouble(Value);

break;

case CLI.FieldType.cli_asciiz:

case CLI.FieldType.cli_pasciiz:

string s   = Value.ToString();

IntPtr str = Marshal.StringToHGlobalAnsi(s);

//纠正中文字符截取错误的问题

try {

CopyBufferData((CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type, bytelengh(s), str);

}

finally {

Marshal.FreeCoTaskMem(str);

}

break;

case CLI.FieldType.cli_array_of_int1:

if (Value is byte[]) {

byte[] arr = (byte[])Value;

int len = arr.Length;

SetBufferTypeAndSize((CLI.UnmanagedBuffer*)buffer.ToPointer(), CLI.FieldType.cli_array_of_int1, len, false);

byte* dst = (byte*)((CLI.UnmanagedBuffer*)buffer.ToPointer())->data.ToPointer();

for (int i = 0; i < len; i++) {

*dst++ = arr[i];

}

break;

} else {

throw new CliError("getValue: Unsupported conversion type! "+Enum.GetName(typeof(CLI.FieldType), ((CLI.UnmanagedBuffer*)buffer.ToPointer())->type));

}

default:

throw new CliError("Unsupported type: "+Enum.GetName(typeof(CLI.FieldType), (CLI.FieldType)((CLI.UnmanagedBuffer*)buffer.ToPointer())->type));

}

}

也可以使用System.Text.Encoding.Default.GetBytes(s).Length,不过如果是奇葩系统长度可能会有变化,没测试过,有兴趣的同学可以试下

希望能对使用c#开发fastdb的朋友有所帮助

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 01:44:57

Fastdb 之中文字符截取错误的问题的相关文章

php中截取中文字符会出现乱码的问题

php中内置函数substr()可以对指定字符串进行截取,不过,它只对全英文字符串的截取是比较适合的.如果字符串中出现了中文,就有可能导致截取后出现乱码的问题,甚至在一些场景中如json编码的时候会导致输出结果为null. 原因是不同字符集中每个字符占用的字节数不一样,如UTF-8编码中每个汉字占3字节,而GB2312汉字占2字节,英文则都只占1字节.确切的说substr()中后两个参数指定的是字节数量而不是字符数量,所以就有可能出现最后一个汉字字符截取不完整的情况从而出现中文乱码. 遇到中文字

【转载】C# 字符串截取指定长度的中文字符--精点

通常,一个中文会占两个字节的空间.很多语言里,一个中文字符就算是2个字符长度. 但在C#中,string里包含的中文字符只占一个字符长度.这就导致很多时候,使用string.SubString(int startIndex,int length)方法来截取字符会错位. 最近由于工作原因,会截取指定长度的字符来使用.但是在文档里,1个中文是2个长度来计算.刚开始还只是以为文档错误,后来才知道是由于C#的差异造成的. 刚开始,是直接到网上找算法,但是找到的算法,基本思路都是挨个字符判断(根据ASCI

Mysql插入数据里有中文字符出现Incorrect string value的错误

问题:Mysql插入数据里有中文字符出现Incorrect string value的错误 描述:CMD里直接敲代码插入数据 提示的部分截取为:ERROR 1366 (HY000): Incorrect string value 一般都是编码问题,show variables like 'character%' 查看后,发现所有编码都为UTF8,并没有错. 也有一种可能是CMD黑窗口的文字编码问题,试着先设置客户端命令的编码,再插入果然正确!然后百度搜索客户端编码相关的问题也发现有和我出现过同样

解决出现乱码substr截取中文字符 siluke123

siluke123< ?php echo mb_substr('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');?>输出:这样一来我的字< ?phpecho mb_strcut('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');?>输出:这样 string mb_strcut ( string $str , int $start [, int $length [, string $encoding ] )mb_strcut() 和 m

截取中文字符长度(中文、字母都有效)

以下给大家分享下:"中文字符长度,和截取中文字符(字母汉字通用)" 样例:先算出字符的长度,在截取显示,日过字符长度超过6就用...取代 echo '<meta http-equiv="content-type" content="text/html;charset=utf-8"/>'; $CustomizedInfo = '美日汇购物返利网http://www.hnzyxok.com/'; if(mb_strlen($Customi

Navicat for MySql 输入中文字符,提示1366错误的解决方法

若表格已经保存了默认的字符集,无法输入中文字符 此时,选中该表,设计表,选择要输入中文字符的列,修改其"字符集"和"排序规则"为截图所示,即可! 其他方式的错误,可参考 https://blog.csdn.net/ZhouSanduo18/article/details/47905419 这个写的很全面 原文地址:https://www.cnblogs.com/sky-x2017/p/mysql1.html

Atitit.404错误解决标准流程and url汉字中文路径404错误resin4 resin chinese char path 404 err解决

Atitit.404错误解决标准流程and url汉字中文路径404错误resin4 resin chinese char path 404 err解决 1. #原因解析 1 2. #解决方式 2 3. 输出图片流... 2 4. --code 2 5. 参考 3 1. #原因解析 查看累挂发送d url,,,俄使用的是ff..它把url转换成个 http://localhost/img/QQ%E6%88%AA%E5%9B%BE20140401175433.jpg 发送出去..每汉字3个%字符,

php中文字符串截取方法实例总结

本文实例总结了php中文字符串截取方法,非常实用的技巧.具体方法分析如下: 1.使用mbstring扩展库的mb_substr截取就不会出现乱码了. 2.自己书写截取函数,但效率不如用mbstring扩展库来得高. 3.如果仅是为了输出截取的串,可用如下方式实现:substr($str, 0, 30).chr(0). substr()函数可以分割文字,但要分割的文字如果包括中文字符往往会遇到问题,这时可以用mb_substr()/mb_strcut这个函 数,mb_substr()/mb_str

boost.xml_parser中文字符问题

当使用xml_parser进行读xml时,如果遇到中文字符会出现解析错误. 网上有解决方案说使用wptree来实现,但当使用wptree来写xml时也会出错.而使用ptree来写中文时不会出错. 综合以上信息,尝试使用ptree来写xml,而用wptree来读.以一个demo来说明吧. 1 //包含文件2 #include <boost/property_tree/ptree.hpp>3 #include <boost/property_tree/xml_parser.hpp>4