问题:字节数组包含取值为0,字符串会把0当成结束符而出错。Base64编解码暂不考虑,原因是性能不满足,因为字节数组最大可达到100M
15 个解决方案
#1
网络传输设置的是传输的字节个数吧,不是靠结束符来判断的吧?
#2
不是底层,是thrift
#3
没明白楼主意思,说的不清楚。
不支持C++数组,那支持什么?
用的什么语言?
可以用unsigned char arr[]?
thrift介绍上说支持C++,这个没用过
不支持C++数组,那支持什么?
用的什么语言?
可以用unsigned char arr[]?
thrift介绍上说支持C++,这个没用过
#4
解释3楼的疑问:thrift定义的字节数组这个数据类型是binary,生成java代码对应的是ByteBuffer,生成C++代码对应的却是string,官网上也是描述的binary只适用java。
因为要传递的是字节数组,而对于C++和java都支持的thrift数据类型是string,因此考虑在数据传输前将字节数组转成string再传输。
因为要传递的是字节数组,而对于C++和java都支持的thrift数据类型是string,因此考虑在数据传输前将字节数组转成string再传输。
#5
那就把binary转换成hex的字符串,然后再进行传输,这样就会加大传输量
另一端同样反转换就可以了
另一端同样反转换就可以了
#6
#7
这种方式占用太多资源,还是优先考虑二进制方式传输
#8
thrift会把binary转换成string,而string本身就是遇到0就结束。这是矛盾的。
资源会增加一倍的消耗,这个看选择了。
如果很大可以把hex string压缩一下再传输。
再或者想办法设置thrift把binary转换的时候,直接转换成C++的binary
资源会增加一倍的消耗,这个看选择了。
如果很大可以把hex string压缩一下再传输。
再或者想办法设置thrift把binary转换的时候,直接转换成C++的binary
#9
C++有binary数据类型吗,网上没搜到,是否有资料共享下
#10
以前我用string存储过含有0的数据。
这种方法属于非常规的方法,这种非常规的方法是用起来要小心。
仅供参考
这种方法属于非常规的方法,这种非常规的方法是用起来要小心。
仅供参考
#include <iostream>
#include <string>
using namespace std;
void printstr(string s)
{
cout<<"size = "<<s.size()<<endl;
string::iterator it = s.begin();
for (; it != s.end(); it++)
{
cout<<*it;
}
}
void main()
{
char arr[] = "this is a test string";
string src = arr;
char* p = (char*)src.c_str();
p[2] = '\0';
printstr(src);
return;
}
#11
好像不少人这样用。
#include <string>
namespace std{
typedef unsigned char byte;
typedef basic_string<byte, char_traits<byte>, allocator<byte>> sbyte;
}
#12
void HexDump(char *buf,int len) {
int i,j,k;
char binstr[80];
for (i=0;i<len;i++) {
if (0==(i%16)) {
sprintf(binstr,"%04x -",i);
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
} else if (15==(i%16)) {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
sprintf(binstr,"%s ",binstr);
for (j=i-15;j<=i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
printf("%s\n",binstr);
} else {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
}
}
if (0!=(i%16)) {
k=16-(i%16);
for (j=0;j<k;j++) {
sprintf(binstr,"%s ",binstr);
}
sprintf(binstr,"%s ",binstr);
k=16-k;
for (j=i-k;j<i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
printf("%s\n",binstr);
}
}
#13
多谢各位,问题已经解决,不需要再做字符串转换了。
java发送给C++:java使用ByteBuffer发送没有问题。C++读取没有问题,因为thrift在字符串前面加了长度(ByteBuffer中的字节长度),长度也发给了C++,C++按照这个长度读取字符串,没有问题。
C++发送给java:C++发送存在问题,因为调用了string的size()方法获取字符串长度,遇到'\0'截止了。java按照ByteBuffer读没有问题。
因此,只要string的size()方法能够返回实际长度,忽略string中间'\0'就能解决问题了。具体可以使用string的assign()方法或者构造函数指定大小,则size()方法可以忽略中间的'\0。
测试代码:
测试结果:
size=20
length=20
0 1 2 3 4 5 6 7 8 0 10 11 12 13 14 15 16 17 18 0
java发送给C++:java使用ByteBuffer发送没有问题。C++读取没有问题,因为thrift在字符串前面加了长度(ByteBuffer中的字节长度),长度也发给了C++,C++按照这个长度读取字符串,没有问题。
C++发送给java:C++发送存在问题,因为调用了string的size()方法获取字符串长度,遇到'\0'截止了。java按照ByteBuffer读没有问题。
因此,只要string的size()方法能够返回实际长度,忽略string中间'\0'就能解决问题了。具体可以使用string的assign()方法或者构造函数指定大小,则size()方法可以忽略中间的'\0。
测试代码:
std::string str;
unsigned char buff[20];
int maxSize = 20;
for (int i=0; i<maxSize; i++)
{
buff[i] = i;
}
buff[9] = 0;
buff[19] = 0;
str.assign((const char *)buff, maxSize);
printf("size=%d\n", str.size());
printf("length=%d\n", str.length());
for (int i=0; i<maxSize; i++)
{
printf("%d ", str.at(i));
}
printf("\n");
测试结果:
size=20
length=20
0 1 2 3 4 5 6 7 8 0 10 11 12 13 14 15 16 17 18 0
#14
ok,今天结贴
#15
小心长度超长!
#1
网络传输设置的是传输的字节个数吧,不是靠结束符来判断的吧?
#2
不是底层,是thrift
#3
没明白楼主意思,说的不清楚。
不支持C++数组,那支持什么?
用的什么语言?
可以用unsigned char arr[]?
thrift介绍上说支持C++,这个没用过
不支持C++数组,那支持什么?
用的什么语言?
可以用unsigned char arr[]?
thrift介绍上说支持C++,这个没用过
#4
解释3楼的疑问:thrift定义的字节数组这个数据类型是binary,生成java代码对应的是ByteBuffer,生成C++代码对应的却是string,官网上也是描述的binary只适用java。
因为要传递的是字节数组,而对于C++和java都支持的thrift数据类型是string,因此考虑在数据传输前将字节数组转成string再传输。
因为要传递的是字节数组,而对于C++和java都支持的thrift数据类型是string,因此考虑在数据传输前将字节数组转成string再传输。
#5
那就把binary转换成hex的字符串,然后再进行传输,这样就会加大传输量
另一端同样反转换就可以了
另一端同样反转换就可以了
#6
#7
这种方式占用太多资源,还是优先考虑二进制方式传输
#8
thrift会把binary转换成string,而string本身就是遇到0就结束。这是矛盾的。
资源会增加一倍的消耗,这个看选择了。
如果很大可以把hex string压缩一下再传输。
再或者想办法设置thrift把binary转换的时候,直接转换成C++的binary
资源会增加一倍的消耗,这个看选择了。
如果很大可以把hex string压缩一下再传输。
再或者想办法设置thrift把binary转换的时候,直接转换成C++的binary
#9
C++有binary数据类型吗,网上没搜到,是否有资料共享下
#10
以前我用string存储过含有0的数据。
这种方法属于非常规的方法,这种非常规的方法是用起来要小心。
仅供参考
这种方法属于非常规的方法,这种非常规的方法是用起来要小心。
仅供参考
#include <iostream>
#include <string>
using namespace std;
void printstr(string s)
{
cout<<"size = "<<s.size()<<endl;
string::iterator it = s.begin();
for (; it != s.end(); it++)
{
cout<<*it;
}
}
void main()
{
char arr[] = "this is a test string";
string src = arr;
char* p = (char*)src.c_str();
p[2] = '\0';
printstr(src);
return;
}
#11
好像不少人这样用。
#include <string>
namespace std{
typedef unsigned char byte;
typedef basic_string<byte, char_traits<byte>, allocator<byte>> sbyte;
}
#12
void HexDump(char *buf,int len) {
int i,j,k;
char binstr[80];
for (i=0;i<len;i++) {
if (0==(i%16)) {
sprintf(binstr,"%04x -",i);
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
} else if (15==(i%16)) {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
sprintf(binstr,"%s ",binstr);
for (j=i-15;j<=i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
printf("%s\n",binstr);
} else {
sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);
}
}
if (0!=(i%16)) {
k=16-(i%16);
for (j=0;j<k;j++) {
sprintf(binstr,"%s ",binstr);
}
sprintf(binstr,"%s ",binstr);
k=16-k;
for (j=i-k;j<i;j++) {
sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');
}
printf("%s\n",binstr);
}
}
#13
多谢各位,问题已经解决,不需要再做字符串转换了。
java发送给C++:java使用ByteBuffer发送没有问题。C++读取没有问题,因为thrift在字符串前面加了长度(ByteBuffer中的字节长度),长度也发给了C++,C++按照这个长度读取字符串,没有问题。
C++发送给java:C++发送存在问题,因为调用了string的size()方法获取字符串长度,遇到'\0'截止了。java按照ByteBuffer读没有问题。
因此,只要string的size()方法能够返回实际长度,忽略string中间'\0'就能解决问题了。具体可以使用string的assign()方法或者构造函数指定大小,则size()方法可以忽略中间的'\0。
测试代码:
测试结果:
size=20
length=20
0 1 2 3 4 5 6 7 8 0 10 11 12 13 14 15 16 17 18 0
java发送给C++:java使用ByteBuffer发送没有问题。C++读取没有问题,因为thrift在字符串前面加了长度(ByteBuffer中的字节长度),长度也发给了C++,C++按照这个长度读取字符串,没有问题。
C++发送给java:C++发送存在问题,因为调用了string的size()方法获取字符串长度,遇到'\0'截止了。java按照ByteBuffer读没有问题。
因此,只要string的size()方法能够返回实际长度,忽略string中间'\0'就能解决问题了。具体可以使用string的assign()方法或者构造函数指定大小,则size()方法可以忽略中间的'\0。
测试代码:
std::string str;
unsigned char buff[20];
int maxSize = 20;
for (int i=0; i<maxSize; i++)
{
buff[i] = i;
}
buff[9] = 0;
buff[19] = 0;
str.assign((const char *)buff, maxSize);
printf("size=%d\n", str.size());
printf("length=%d\n", str.length());
for (int i=0; i<maxSize; i++)
{
printf("%d ", str.at(i));
}
printf("\n");
测试结果:
size=20
length=20
0 1 2 3 4 5 6 7 8 0 10 11 12 13 14 15 16 17 18 0
#14
ok,今天结贴
#15
小心长度超长!