C++拜訪Redis的mset 二進制數據接口封裝計劃。本站提示廣大學習愛好者:(C++拜訪Redis的mset 二進制數據接口封裝計劃)文章只能為提供參考,不一定能成為您想要的結果。以下是C++拜訪Redis的mset 二進制數據接口封裝計劃正文
需求
C++中應用hiredis客戶端接口拜訪redis;
須要應用mset一次設置多個二進制數據
以下給出三種封裝完成計劃;
簡略拼接計劃
在redis-cli中,mset的語法是如許的:
/opt/colin$./redis-cli mset a 11 b 22 c 333
OK
依照如許的語法拼接後,直接應用hiredis字符串接口redisCommand傳遞:
void msetNotBinary(redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal ) { if(vtKey.size() != vtVal.size()) { throw runtime_error( "Redis error" ); } string strCmd = "MSET"; for(int i = 0; i < vtKey.size(); i++) { strCmd += " "+vtKey[i]+" "+vtVal[i]; } cout << "strCmd:" << strCmd << endl; void * r = redisCommand(c, strCmd.c_str() ); if ( !r ) throw runtime_error( "Redis error" ); freeReplyObject( r ); } void do_test( redisContext *c ) { vector<string> vtKey; vector<string> vtVal; vtKey.push_back("A"); vtVal.push_back("AAAA"); vtKey.push_back("B"); vtVal.push_back("BBBB"); vtKey.push_back("C"); vtVal.push_back("CCCC"); //add a binary data vtKey.push_back("D"); vtVal.push_back(""); char a[] = "ABCDE"; a[2] = 0; vtVal[3].assign(a,5); try { msetNotBinary(c, vtKey, vtVal ); //mset1( c, vtKey, vtVal ); //mset2( c, vtKey, vtVal ); } catch ( runtime_error & ) { cout << "Error" << endl; } } int main(int argc, char *argv[]) { redisContext *c; c = redisConnect("127.0.0.1",6379); if (c->err) { cout << "Connection error: " << c->errstr << endl; return -1; } do_test(c); redisFree(c); return 0; }
這類方法可以處置mset多個字符串數據,但關於數據內容為二進制數據的力所不及;
redisCommandArgv接口授遞 計劃
關於多個參數傳遞,hiredis供給了以下接口,這個接口中最初一個參數是一切的傳入數據的內容長度,
就是說這個接口是二進制平安的:
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
重要任務就是結構一個靜態的二維數組char ** argv,個中觸及到char **到const char **的轉換,有必定的風險,
關於這一點前一篇文章曾經談到;
void mset1( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal ) { if(vtKey.size() != vtVal.size()) { throw runtime_error( "Redis error" ); } char ** argv = new char*[vtKey.size() + vtVal.size() + 1 ]; size_t * argvlen = new size_t[vtKey.size() + vtVal.size() + 1 ]; int j = 0; argv[j] = new char[5]; memcpy(argv[j],"MSET",4); argvlen[j] = 4; ++j; for(int i = 0 ; i < vtKey.size();i++) { argvlen[j] = vtKey[i].length(); argv[j] = new char[argvlen[j]]; memset((void*)argv[j],0,argvlen[j] ); memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length()); j++; argvlen[j] = vtVal[i].length(); argv[j] = new char[argvlen[j]]; memset((void*)argv[j],0,argvlen[j]); memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length()); j++; } //if not use const_cast<const char**> ,compile error //for why assign from char** to const char** error, see my blog ... void *r = redisCommandArgv(c, vtKey.size() + vtVal.size() + 1, const_cast<const char**>(argv), argvlen ); if ( !r ) throw runtime_error( "Redis error" ); freeReplyObject( r ); for(int i = 0;i < vtKey.size();i++) { delete [] argv[i]; argv[i] = NULL; } delete []argv; delete []argvlen; argv = NULL; }
redisCommandArgv接口授遞的Vector計劃
照樣應用redisCommandArgv接口,應用vector來結構這個const char **,這個辦法是從參考材料1中學到的:
void mset2( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal) { if(vtKey.size() != vtVal.size()) { throw runtime_error( "Redis error" ); } vector<const char *> argv( vtKey.size() + vtVal.size() + 1 ); vector<size_t> argvlen( vtKey.size() + vtVal.size() + 1 ); int j = 0; static char msetcmd[] = "MSET"; argv[j] = msetcmd; argvlen[j] = sizeof(msetcmd)-1; ++j; for(int i = 0;i< vtKey.size();++i) { argvlen[j] = vtKey[i].length(); argv[j] = new char[argvlen[j]]; memset((void*)argv[j],0,argvlen[j] ); memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length()); j++; argvlen[j] = vtVal[i].length(); argv[j] = new char[argvlen[j]]; memset((void*)argv[j],0,argvlen[j]); memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length()); j++; } void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) ); if ( !r ) throw runtime_error( "Redis error" ); freeReplyObject( r ); }
如許,就完成二進制數據的傳遞;
二進制校驗
法式履行後,可以用redis-cli來驗證:
關於非二進制平安的完成,二進制內容是截斷的:
/opt/app/colin$./redis-cli get D
"AB"
而二進制平安的完成接口,二進制數據的0經由過程本義方法顯示:
/opt/app/colin$./redis-cli get D
"AB\x00DE"
完全可履行的代碼詳見github:https://github.com/me115/cppset/tree/master/2DimArray
以上所述就是本文的全體內容了,願望年夜家可以或許愛好。