关于Qt使用Redis数据库问题
Windows环境下,使用Qt C++连接Redis数据库的第三方库在网上很难找,资源很少。我找了好久找到一个名为QtRedis-master的开源库,可以使用,但是不支持中文。输入中文无论是存到数据库里,还是从数据库读出都是乱码,并且存储的信息不全。研究了一个星期,终于找到了病因。我把它分享出来,愿对大家有帮助。Redis-cli客户端和Redis-serve...
Windows环境下,使用Qt C++连接Redis数据库的第三方库在网上很难找,资源很少。我找了好久找到一个名为QtRedis-master的开源库,可以使用,但是不支持中文。输入中文无论是存到数据库里,还是从数据库读出都是乱码,并且存储的信息不全。研究了一个星期,终于找到了病因。我把它分享出来,愿对大家有帮助。
Redis-cli客户端和Redis-server服务端通讯采用的是Redis Resp协议,汉字的通讯编码格式是utf-8。windows中命令行模式下,默认的是GBK编码格式,要想正常在命令行模式下显示汉字必须存入Redis数据库的汉字编码格式也为GBK才行。但是若使用QtRedis-master库在Qt里做了编码格式转换,输入汉字依旧还会显示乱码。
通过网络抓包发现,在QtRedis-master库中,向数据库发送数据时是按照英文字母的读取方式进行发送的,即每个字母按utf8转换成十六进制的一个字节。在读取汉字的时候也是按照一个字节计算,而按照Resp协议通讯时,每个汉字按照utf8编码转换成了十六进制的三个字节,这就是存入数据库后为什么显示乱码和存储不全的原因。
把库中reader.cpp文件里的sendData发送数据函数和socketReadyRead读取数据函数做了一下修改。
void Reader::socketReadyRead()
{
QString reply("");
QByteArray qb_array;
qb_array.resize(socket->readBufferSize()); //把原按照字符串读取改成按照字节读取
qb_array=socket->readAll();
//reply.append(qb_array);
reply=QTextCodec::codecForName("GBK")->toUnicode(qb_array); //将编码格式转换成GBK
readLine(reply);
}
这样就确保了显示不会乱码。
//... 在sendData发送数据函数中将原字符流方式发送改成按照字节方式发送,这样就可以确保汉字编码后,字符串长度和编码长度一致。
QByteArray qb_array;
qb_array.clear();
qb_array.append(QString("*%1\r\n").arg(parts.length()));
int i;
for(i=0;i<parts.length();i++)
{
QString qs_part_i=parts.at(i);
QByteArray qb_byte=qs_part_i.toLocal8Bit();
qb_array.append(QString("$%1\r\n").arg(qb_byte.length()));
for(int j=0;j<qb_byte.length();j++)
{
qb_array.append(qb_byte[j]);
}
qb_array.append(0x0D);
qb_array.append(0x0A);
}
int i_len =qb_array.length();
socket->write(qb_array,i_len);
while(!socket->waitForBytesWritten())
{
}
这样修改后,开源的QtRedis-master库就支持中文了。如果你是拿redis-cli的客户端查看数据库内容,记着使用redis-cli --raw打开客户端,这样才能正常显示汉字在客户端界面。
更多推荐
所有评论(0)